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 #include "v8.h"
     29 
     30 #include "bootstrapper.h"
     31 #include "codegen-inl.h"
     32 #include "compiler.h"
     33 #include "debug.h"
     34 #include "ic-inl.h"
     35 #include "jsregexp.h"
     36 #include "parser.h"
     37 #include "regexp-macro-assembler.h"
     38 #include "regexp-stack.h"
     39 #include "register-allocator-inl.h"
     40 #include "runtime.h"
     41 #include "scopes.h"
     42 
     43 namespace v8 {
     44 namespace internal {
     45 
     46 #define __ ACCESS_MASM(masm_)
     47 
     48 // -------------------------------------------------------------------------
     49 // Platform-specific DeferredCode functions.
     50 
     51 void DeferredCode::SaveRegisters() {
     52   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
     53     int action = registers_[i];
     54     if (action == kPush) {
     55       __ push(RegisterAllocator::ToRegister(i));
     56     } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
     57       __ mov(Operand(ebp, action), RegisterAllocator::ToRegister(i));
     58     }
     59   }
     60 }
     61 
     62 
     63 void DeferredCode::RestoreRegisters() {
     64   // Restore registers in reverse order due to the stack.
     65   for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
     66     int action = registers_[i];
     67     if (action == kPush) {
     68       __ pop(RegisterAllocator::ToRegister(i));
     69     } else if (action != kIgnore) {
     70       action &= ~kSyncedFlag;
     71       __ mov(RegisterAllocator::ToRegister(i), Operand(ebp, action));
     72     }
     73   }
     74 }
     75 
     76 
     77 // -------------------------------------------------------------------------
     78 // CodeGenState implementation.
     79 
     80 CodeGenState::CodeGenState(CodeGenerator* owner)
     81     : owner_(owner),
     82       destination_(NULL),
     83       previous_(NULL) {
     84   owner_->set_state(this);
     85 }
     86 
     87 
     88 CodeGenState::CodeGenState(CodeGenerator* owner,
     89                            ControlDestination* destination)
     90     : owner_(owner),
     91       destination_(destination),
     92       previous_(owner->state()) {
     93   owner_->set_state(this);
     94 }
     95 
     96 
     97 CodeGenState::~CodeGenState() {
     98   ASSERT(owner_->state() == this);
     99   owner_->set_state(previous_);
    100 }
    101 
    102 
    103 // -------------------------------------------------------------------------
    104 // CodeGenerator implementation
    105 
    106 CodeGenerator::CodeGenerator(MacroAssembler* masm)
    107     : deferred_(8),
    108       masm_(masm),
    109       info_(NULL),
    110       frame_(NULL),
    111       allocator_(NULL),
    112       state_(NULL),
    113       loop_nesting_(0),
    114       function_return_is_shadowed_(false),
    115       in_spilled_code_(false) {
    116 }
    117 
    118 
    119 Scope* CodeGenerator::scope() { return info_->function()->scope(); }
    120 
    121 
    122 // Calling conventions:
    123 // ebp: caller's frame pointer
    124 // esp: stack pointer
    125 // edi: called JS function
    126 // esi: callee's context
    127 
    128 void CodeGenerator::Generate(CompilationInfo* info) {
    129   // Record the position for debugging purposes.
    130   CodeForFunctionPosition(info->function());
    131 
    132   // Initialize state.
    133   info_ = info;
    134   ASSERT(allocator_ == NULL);
    135   RegisterAllocator register_allocator(this);
    136   allocator_ = &register_allocator;
    137   ASSERT(frame_ == NULL);
    138   frame_ = new VirtualFrame();
    139   set_in_spilled_code(false);
    140 
    141   // Adjust for function-level loop nesting.
    142   loop_nesting_ += info->loop_nesting();
    143 
    144   JumpTarget::set_compiling_deferred_code(false);
    145 
    146 #ifdef DEBUG
    147   if (strlen(FLAG_stop_at) > 0 &&
    148       info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
    149     frame_->SpillAll();
    150     __ int3();
    151   }
    152 #endif
    153 
    154   // New scope to get automatic timing calculation.
    155   {  // NOLINT
    156     HistogramTimerScope codegen_timer(&Counters::code_generation);
    157     CodeGenState state(this);
    158 
    159     // Entry:
    160     // Stack: receiver, arguments, return address.
    161     // ebp: caller's frame pointer
    162     // esp: stack pointer
    163     // edi: called JS function
    164     // esi: callee's context
    165     allocator_->Initialize();
    166 
    167     if (info->mode() == CompilationInfo::PRIMARY) {
    168       frame_->Enter();
    169 
    170       // Allocate space for locals and initialize them.
    171       frame_->AllocateStackSlots();
    172 
    173       // Allocate the local context if needed.
    174       int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
    175       if (heap_slots > 0) {
    176         Comment cmnt(masm_, "[ allocate local context");
    177         // Allocate local context.
    178         // Get outer context and create a new context based on it.
    179         frame_->PushFunction();
    180         Result context;
    181         if (heap_slots <= FastNewContextStub::kMaximumSlots) {
    182           FastNewContextStub stub(heap_slots);
    183           context = frame_->CallStub(&stub, 1);
    184         } else {
    185           context = frame_->CallRuntime(Runtime::kNewContext, 1);
    186         }
    187 
    188         // Update context local.
    189         frame_->SaveContextRegister();
    190 
    191         // Verify that the runtime call result and esi agree.
    192         if (FLAG_debug_code) {
    193           __ cmp(context.reg(), Operand(esi));
    194           __ Assert(equal, "Runtime::NewContext should end up in esi");
    195         }
    196       }
    197 
    198       // TODO(1241774): Improve this code:
    199       // 1) only needed if we have a context
    200       // 2) no need to recompute context ptr every single time
    201       // 3) don't copy parameter operand code from SlotOperand!
    202       {
    203         Comment cmnt2(masm_, "[ copy context parameters into .context");
    204         // Note that iteration order is relevant here! If we have the same
    205         // parameter twice (e.g., function (x, y, x)), and that parameter
    206         // needs to be copied into the context, it must be the last argument
    207         // passed to the parameter that needs to be copied. This is a rare
    208         // case so we don't check for it, instead we rely on the copying
    209         // order: such a parameter is copied repeatedly into the same
    210         // context location and thus the last value is what is seen inside
    211         // the function.
    212         for (int i = 0; i < scope()->num_parameters(); i++) {
    213           Variable* par = scope()->parameter(i);
    214           Slot* slot = par->slot();
    215           if (slot != NULL && slot->type() == Slot::CONTEXT) {
    216             // The use of SlotOperand below is safe in unspilled code
    217             // because the slot is guaranteed to be a context slot.
    218             //
    219             // There are no parameters in the global scope.
    220             ASSERT(!scope()->is_global_scope());
    221             frame_->PushParameterAt(i);
    222             Result value = frame_->Pop();
    223             value.ToRegister();
    224 
    225             // SlotOperand loads context.reg() with the context object
    226             // stored to, used below in RecordWrite.
    227             Result context = allocator_->Allocate();
    228             ASSERT(context.is_valid());
    229             __ mov(SlotOperand(slot, context.reg()), value.reg());
    230             int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
    231             Result scratch = allocator_->Allocate();
    232             ASSERT(scratch.is_valid());
    233             frame_->Spill(context.reg());
    234             frame_->Spill(value.reg());
    235             __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
    236           }
    237         }
    238       }
    239 
    240       // Store the arguments object.  This must happen after context
    241       // initialization because the arguments object may be stored in
    242       // the context.
    243       if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
    244         StoreArgumentsObject(true);
    245       }
    246 
    247       // Initialize ThisFunction reference if present.
    248       if (scope()->is_function_scope() && scope()->function() != NULL) {
    249         frame_->Push(Factory::the_hole_value());
    250         StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT);
    251       }
    252     } else {
    253       // When used as the secondary compiler for splitting, ebp, esi,
    254       // and edi have been pushed on the stack.  Adjust the virtual
    255       // frame to match this state.
    256       frame_->Adjust(3);
    257       allocator_->Unuse(edi);
    258 
    259       // Bind all the bailout labels to the beginning of the function.
    260       List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
    261       for (int i = 0; i < bailouts->length(); i++) {
    262         __ bind(bailouts->at(i)->label());
    263       }
    264     }
    265 
    266     // Initialize the function return target after the locals are set
    267     // up, because it needs the expected frame height from the frame.
    268     function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
    269     function_return_is_shadowed_ = false;
    270 
    271     // Generate code to 'execute' declarations and initialize functions
    272     // (source elements). In case of an illegal redeclaration we need to
    273     // handle that instead of processing the declarations.
    274     if (scope()->HasIllegalRedeclaration()) {
    275       Comment cmnt(masm_, "[ illegal redeclarations");
    276       scope()->VisitIllegalRedeclaration(this);
    277     } else {
    278       Comment cmnt(masm_, "[ declarations");
    279       ProcessDeclarations(scope()->declarations());
    280       // Bail out if a stack-overflow exception occurred when processing
    281       // declarations.
    282       if (HasStackOverflow()) return;
    283     }
    284 
    285     if (FLAG_trace) {
    286       frame_->CallRuntime(Runtime::kTraceEnter, 0);
    287       // Ignore the return value.
    288     }
    289     CheckStack();
    290 
    291     // Compile the body of the function in a vanilla state. Don't
    292     // bother compiling all the code if the scope has an illegal
    293     // redeclaration.
    294     if (!scope()->HasIllegalRedeclaration()) {
    295       Comment cmnt(masm_, "[ function body");
    296 #ifdef DEBUG
    297       bool is_builtin = Bootstrapper::IsActive();
    298       bool should_trace =
    299           is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
    300       if (should_trace) {
    301         frame_->CallRuntime(Runtime::kDebugTrace, 0);
    302         // Ignore the return value.
    303       }
    304 #endif
    305       VisitStatements(info->function()->body());
    306 
    307       // Handle the return from the function.
    308       if (has_valid_frame()) {
    309         // If there is a valid frame, control flow can fall off the end of
    310         // the body.  In that case there is an implicit return statement.
    311         ASSERT(!function_return_is_shadowed_);
    312         CodeForReturnPosition(info->function());
    313         frame_->PrepareForReturn();
    314         Result undefined(Factory::undefined_value());
    315         if (function_return_.is_bound()) {
    316           function_return_.Jump(&undefined);
    317         } else {
    318           function_return_.Bind(&undefined);
    319           GenerateReturnSequence(&undefined);
    320         }
    321       } else if (function_return_.is_linked()) {
    322         // If the return target has dangling jumps to it, then we have not
    323         // yet generated the return sequence.  This can happen when (a)
    324         // control does not flow off the end of the body so we did not
    325         // compile an artificial return statement just above, and (b) there
    326         // are return statements in the body but (c) they are all shadowed.
    327         Result return_value;
    328         function_return_.Bind(&return_value);
    329         GenerateReturnSequence(&return_value);
    330       }
    331     }
    332   }
    333 
    334   // Adjust for function-level loop nesting.
    335   loop_nesting_ -= info->loop_nesting();
    336 
    337   // Code generation state must be reset.
    338   ASSERT(state_ == NULL);
    339   ASSERT(loop_nesting() == 0);
    340   ASSERT(!function_return_is_shadowed_);
    341   function_return_.Unuse();
    342   DeleteFrame();
    343 
    344   // Process any deferred code using the register allocator.
    345   if (!HasStackOverflow()) {
    346     HistogramTimerScope deferred_timer(&Counters::deferred_code_generation);
    347     JumpTarget::set_compiling_deferred_code(true);
    348     ProcessDeferred();
    349     JumpTarget::set_compiling_deferred_code(false);
    350   }
    351 
    352   // There is no need to delete the register allocator, it is a
    353   // stack-allocated local.
    354   allocator_ = NULL;
    355 }
    356 
    357 
    358 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
    359   // Currently, this assertion will fail if we try to assign to
    360   // a constant variable that is constant because it is read-only
    361   // (such as the variable referring to a named function expression).
    362   // We need to implement assignments to read-only variables.
    363   // Ideally, we should do this during AST generation (by converting
    364   // such assignments into expression statements); however, in general
    365   // we may not be able to make the decision until past AST generation,
    366   // that is when the entire program is known.
    367   ASSERT(slot != NULL);
    368   int index = slot->index();
    369   switch (slot->type()) {
    370     case Slot::PARAMETER:
    371       return frame_->ParameterAt(index);
    372 
    373     case Slot::LOCAL:
    374       return frame_->LocalAt(index);
    375 
    376     case Slot::CONTEXT: {
    377       // Follow the context chain if necessary.
    378       ASSERT(!tmp.is(esi));  // do not overwrite context register
    379       Register context = esi;
    380       int chain_length = scope()->ContextChainLength(slot->var()->scope());
    381       for (int i = 0; i < chain_length; i++) {
    382         // Load the closure.
    383         // (All contexts, even 'with' contexts, have a closure,
    384         // and it is the same for all contexts inside a function.
    385         // There is no need to go to the function context first.)
    386         __ mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
    387         // Load the function context (which is the incoming, outer context).
    388         __ mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset));
    389         context = tmp;
    390       }
    391       // We may have a 'with' context now. Get the function context.
    392       // (In fact this mov may never be the needed, since the scope analysis
    393       // may not permit a direct context access in this case and thus we are
    394       // always at a function context. However it is safe to dereference be-
    395       // cause the function context of a function context is itself. Before
    396       // deleting this mov we should try to create a counter-example first,
    397       // though...)
    398       __ mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
    399       return ContextOperand(tmp, index);
    400     }
    401 
    402     default:
    403       UNREACHABLE();
    404       return Operand(eax);
    405   }
    406 }
    407 
    408 
    409 Operand CodeGenerator::ContextSlotOperandCheckExtensions(Slot* slot,
    410                                                          Result tmp,
    411                                                          JumpTarget* slow) {
    412   ASSERT(slot->type() == Slot::CONTEXT);
    413   ASSERT(tmp.is_register());
    414   Register context = esi;
    415 
    416   for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) {
    417     if (s->num_heap_slots() > 0) {
    418       if (s->calls_eval()) {
    419         // Check that extension is NULL.
    420         __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
    421                Immediate(0));
    422         slow->Branch(not_equal, not_taken);
    423       }
    424       __ mov(tmp.reg(), ContextOperand(context, Context::CLOSURE_INDEX));
    425       __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
    426       context = tmp.reg();
    427     }
    428   }
    429   // Check that last extension is NULL.
    430   __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0));
    431   slow->Branch(not_equal, not_taken);
    432   __ mov(tmp.reg(), ContextOperand(context, Context::FCONTEXT_INDEX));
    433   return ContextOperand(tmp.reg(), slot->index());
    434 }
    435 
    436 
    437 // Emit code to load the value of an expression to the top of the
    438 // frame. If the expression is boolean-valued it may be compiled (or
    439 // partially compiled) into control flow to the control destination.
    440 // If force_control is true, control flow is forced.
    441 void CodeGenerator::LoadCondition(Expression* x,
    442                                   ControlDestination* dest,
    443                                   bool force_control) {
    444   ASSERT(!in_spilled_code());
    445   int original_height = frame_->height();
    446 
    447   { CodeGenState new_state(this, dest);
    448     Visit(x);
    449 
    450     // If we hit a stack overflow, we may not have actually visited
    451     // the expression.  In that case, we ensure that we have a
    452     // valid-looking frame state because we will continue to generate
    453     // code as we unwind the C++ stack.
    454     //
    455     // It's possible to have both a stack overflow and a valid frame
    456     // state (eg, a subexpression overflowed, visiting it returned
    457     // with a dummied frame state, and visiting this expression
    458     // returned with a normal-looking state).
    459     if (HasStackOverflow() &&
    460         !dest->is_used() &&
    461         frame_->height() == original_height) {
    462       dest->Goto(true);
    463     }
    464   }
    465 
    466   if (force_control && !dest->is_used()) {
    467     // Convert the TOS value into flow to the control destination.
    468     ToBoolean(dest);
    469   }
    470 
    471   ASSERT(!(force_control && !dest->is_used()));
    472   ASSERT(dest->is_used() || frame_->height() == original_height + 1);
    473 }
    474 
    475 
    476 void CodeGenerator::LoadAndSpill(Expression* expression) {
    477   ASSERT(in_spilled_code());
    478   set_in_spilled_code(false);
    479   Load(expression);
    480   frame_->SpillAll();
    481   set_in_spilled_code(true);
    482 }
    483 
    484 
    485 void CodeGenerator::Load(Expression* expr) {
    486 #ifdef DEBUG
    487   int original_height = frame_->height();
    488 #endif
    489   ASSERT(!in_spilled_code());
    490   JumpTarget true_target;
    491   JumpTarget false_target;
    492   ControlDestination dest(&true_target, &false_target, true);
    493   LoadCondition(expr, &dest, false);
    494 
    495   if (dest.false_was_fall_through()) {
    496     // The false target was just bound.
    497     JumpTarget loaded;
    498     frame_->Push(Factory::false_value());
    499     // There may be dangling jumps to the true target.
    500     if (true_target.is_linked()) {
    501       loaded.Jump();
    502       true_target.Bind();
    503       frame_->Push(Factory::true_value());
    504       loaded.Bind();
    505     }
    506 
    507   } else if (dest.is_used()) {
    508     // There is true, and possibly false, control flow (with true as
    509     // the fall through).
    510     JumpTarget loaded;
    511     frame_->Push(Factory::true_value());
    512     if (false_target.is_linked()) {
    513       loaded.Jump();
    514       false_target.Bind();
    515       frame_->Push(Factory::false_value());
    516       loaded.Bind();
    517     }
    518 
    519   } else {
    520     // We have a valid value on top of the frame, but we still may
    521     // have dangling jumps to the true and false targets from nested
    522     // subexpressions (eg, the left subexpressions of the
    523     // short-circuited boolean operators).
    524     ASSERT(has_valid_frame());
    525     if (true_target.is_linked() || false_target.is_linked()) {
    526       JumpTarget loaded;
    527       loaded.Jump();  // Don't lose the current TOS.
    528       if (true_target.is_linked()) {
    529         true_target.Bind();
    530         frame_->Push(Factory::true_value());
    531         if (false_target.is_linked()) {
    532           loaded.Jump();
    533         }
    534       }
    535       if (false_target.is_linked()) {
    536         false_target.Bind();
    537         frame_->Push(Factory::false_value());
    538       }
    539       loaded.Bind();
    540     }
    541   }
    542 
    543   ASSERT(has_valid_frame());
    544   ASSERT(frame_->height() == original_height + 1);
    545 }
    546 
    547 
    548 void CodeGenerator::LoadGlobal() {
    549   if (in_spilled_code()) {
    550     frame_->EmitPush(GlobalObject());
    551   } else {
    552     Result temp = allocator_->Allocate();
    553     __ mov(temp.reg(), GlobalObject());
    554     frame_->Push(&temp);
    555   }
    556 }
    557 
    558 
    559 void CodeGenerator::LoadGlobalReceiver() {
    560   Result temp = allocator_->Allocate();
    561   Register reg = temp.reg();
    562   __ mov(reg, GlobalObject());
    563   __ mov(reg, FieldOperand(reg, GlobalObject::kGlobalReceiverOffset));
    564   frame_->Push(&temp);
    565 }
    566 
    567 
    568 void CodeGenerator::LoadTypeofExpression(Expression* expr) {
    569   // Special handling of identifiers as subexpressions of typeof.
    570   Variable* variable = expr->AsVariableProxy()->AsVariable();
    571   if (variable != NULL && !variable->is_this() && variable->is_global()) {
    572     // For a global variable we build the property reference
    573     // <global>.<variable> and perform a (regular non-contextual) property
    574     // load to make sure we do not get reference errors.
    575     Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX);
    576     Literal key(variable->name());
    577     Property property(&global, &key, RelocInfo::kNoPosition);
    578     Reference ref(this, &property);
    579     ref.GetValue();
    580   } else if (variable != NULL && variable->slot() != NULL) {
    581     // For a variable that rewrites to a slot, we signal it is the immediate
    582     // subexpression of a typeof.
    583     Result result =
    584         LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
    585     frame()->Push(&result);
    586   } else {
    587     // Anything else can be handled normally.
    588     Load(expr);
    589   }
    590 }
    591 
    592 
    593 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() {
    594   if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION;
    595   ASSERT(scope()->arguments_shadow() != NULL);
    596   // We don't want to do lazy arguments allocation for functions that
    597   // have heap-allocated contexts, because it interfers with the
    598   // uninitialized const tracking in the context objects.
    599   return (scope()->num_heap_slots() > 0)
    600       ? EAGER_ARGUMENTS_ALLOCATION
    601       : LAZY_ARGUMENTS_ALLOCATION;
    602 }
    603 
    604 
    605 Result CodeGenerator::StoreArgumentsObject(bool initial) {
    606   ArgumentsAllocationMode mode = ArgumentsMode();
    607   ASSERT(mode != NO_ARGUMENTS_ALLOCATION);
    608 
    609   Comment cmnt(masm_, "[ store arguments object");
    610   if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) {
    611     // When using lazy arguments allocation, we store the hole value
    612     // as a sentinel indicating that the arguments object hasn't been
    613     // allocated yet.
    614     frame_->Push(Factory::the_hole_value());
    615   } else {
    616     ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
    617     frame_->PushFunction();
    618     frame_->PushReceiverSlotAddress();
    619     frame_->Push(Smi::FromInt(scope()->num_parameters()));
    620     Result result = frame_->CallStub(&stub, 3);
    621     frame_->Push(&result);
    622   }
    623 
    624   Variable* arguments = scope()->arguments()->var();
    625   Variable* shadow = scope()->arguments_shadow()->var();
    626   ASSERT(arguments != NULL && arguments->slot() != NULL);
    627   ASSERT(shadow != NULL && shadow->slot() != NULL);
    628   JumpTarget done;
    629   bool skip_arguments = false;
    630   if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) {
    631     // We have to skip storing into the arguments slot if it has already
    632     // been written to. This can happen if the a function has a local
    633     // variable named 'arguments'.
    634     Result probe = LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF);
    635     if (probe.is_constant()) {
    636       // We have to skip updating the arguments object if it has
    637       // been assigned a proper value.
    638       skip_arguments = !probe.handle()->IsTheHole();
    639     } else {
    640       __ cmp(Operand(probe.reg()), Immediate(Factory::the_hole_value()));
    641       probe.Unuse();
    642       done.Branch(not_equal);
    643     }
    644   }
    645   if (!skip_arguments) {
    646     StoreToSlot(arguments->slot(), NOT_CONST_INIT);
    647     if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind();
    648   }
    649   StoreToSlot(shadow->slot(), NOT_CONST_INIT);
    650   return frame_->Pop();
    651 }
    652 
    653 //------------------------------------------------------------------------------
    654 // CodeGenerator implementation of variables, lookups, and stores.
    655 
    656 Reference::Reference(CodeGenerator* cgen,
    657                      Expression* expression,
    658                      bool persist_after_get)
    659     : cgen_(cgen),
    660       expression_(expression),
    661       type_(ILLEGAL),
    662       persist_after_get_(persist_after_get) {
    663   cgen->LoadReference(this);
    664 }
    665 
    666 
    667 Reference::~Reference() {
    668   ASSERT(is_unloaded() || is_illegal());
    669 }
    670 
    671 
    672 void CodeGenerator::LoadReference(Reference* ref) {
    673   // References are loaded from both spilled and unspilled code.  Set the
    674   // state to unspilled to allow that (and explicitly spill after
    675   // construction at the construction sites).
    676   bool was_in_spilled_code = in_spilled_code_;
    677   in_spilled_code_ = false;
    678 
    679   Comment cmnt(masm_, "[ LoadReference");
    680   Expression* e = ref->expression();
    681   Property* property = e->AsProperty();
    682   Variable* var = e->AsVariableProxy()->AsVariable();
    683 
    684   if (property != NULL) {
    685     // The expression is either a property or a variable proxy that rewrites
    686     // to a property.
    687     Load(property->obj());
    688     if (property->key()->IsPropertyName()) {
    689       ref->set_type(Reference::NAMED);
    690     } else {
    691       Load(property->key());
    692       ref->set_type(Reference::KEYED);
    693     }
    694   } else if (var != NULL) {
    695     // The expression is a variable proxy that does not rewrite to a
    696     // property.  Global variables are treated as named property references.
    697     if (var->is_global()) {
    698       // If eax is free, the register allocator prefers it.  Thus the code
    699       // generator will load the global object into eax, which is where
    700       // LoadIC wants it.  Most uses of Reference call LoadIC directly
    701       // after the reference is created.
    702       frame_->Spill(eax);
    703       LoadGlobal();
    704       ref->set_type(Reference::NAMED);
    705     } else {
    706       ASSERT(var->slot() != NULL);
    707       ref->set_type(Reference::SLOT);
    708     }
    709   } else {
    710     // Anything else is a runtime error.
    711     Load(e);
    712     frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
    713   }
    714 
    715   in_spilled_code_ = was_in_spilled_code;
    716 }
    717 
    718 
    719 void CodeGenerator::UnloadReference(Reference* ref) {
    720   // Pop a reference from the stack while preserving TOS.
    721   Comment cmnt(masm_, "[ UnloadReference");
    722   frame_->Nip(ref->size());
    723   ref->set_unloaded();
    724 }
    725 
    726 
    727 // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and
    728 // convert it to a boolean in the condition code register or jump to
    729 // 'false_target'/'true_target' as appropriate.
    730 void CodeGenerator::ToBoolean(ControlDestination* dest) {
    731   Comment cmnt(masm_, "[ ToBoolean");
    732 
    733   // The value to convert should be popped from the frame.
    734   Result value = frame_->Pop();
    735   value.ToRegister();
    736 
    737   if (value.is_number()) {
    738     Comment cmnt(masm_, "ONLY_NUMBER");
    739     // Fast case if NumberInfo indicates only numbers.
    740     if (FLAG_debug_code) {
    741       __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number.");
    742     }
    743     // Smi => false iff zero.
    744     ASSERT(kSmiTag == 0);
    745     __ test(value.reg(), Operand(value.reg()));
    746     dest->false_target()->Branch(zero);
    747     __ test(value.reg(), Immediate(kSmiTagMask));
    748     dest->true_target()->Branch(zero);
    749     __ fldz();
    750     __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset));
    751     __ FCmp();
    752     value.Unuse();
    753     dest->Split(not_zero);
    754   } else {
    755     // Fast case checks.
    756     // 'false' => false.
    757     __ cmp(value.reg(), Factory::false_value());
    758     dest->false_target()->Branch(equal);
    759 
    760     // 'true' => true.
    761     __ cmp(value.reg(), Factory::true_value());
    762     dest->true_target()->Branch(equal);
    763 
    764     // 'undefined' => false.
    765     __ cmp(value.reg(), Factory::undefined_value());
    766     dest->false_target()->Branch(equal);
    767 
    768     // Smi => false iff zero.
    769     ASSERT(kSmiTag == 0);
    770     __ test(value.reg(), Operand(value.reg()));
    771     dest->false_target()->Branch(zero);
    772     __ test(value.reg(), Immediate(kSmiTagMask));
    773     dest->true_target()->Branch(zero);
    774 
    775     // Call the stub for all other cases.
    776     frame_->Push(&value);  // Undo the Pop() from above.
    777     ToBooleanStub stub;
    778     Result temp = frame_->CallStub(&stub, 1);
    779     // Convert the result to a condition code.
    780     __ test(temp.reg(), Operand(temp.reg()));
    781     temp.Unuse();
    782     dest->Split(not_equal);
    783   }
    784 }
    785 
    786 
    787 class FloatingPointHelper : public AllStatic {
    788  public:
    789 
    790   enum ArgLocation {
    791     ARGS_ON_STACK,
    792     ARGS_IN_REGISTERS
    793   };
    794 
    795   // Code pattern for loading a floating point value. Input value must
    796   // be either a smi or a heap number object (fp value). Requirements:
    797   // operand in register number. Returns operand as floating point number
    798   // on FPU stack.
    799   static void LoadFloatOperand(MacroAssembler* masm, Register number);
    800   // Code pattern for loading floating point values. Input values must
    801   // be either smi or heap number objects (fp values). Requirements:
    802   // operand_1 on TOS+1 or in edx, operand_2 on TOS+2 or in eax.
    803   // Returns operands as floating point numbers on FPU stack.
    804   static void LoadFloatOperands(MacroAssembler* masm,
    805                                 Register scratch,
    806                                 ArgLocation arg_location = ARGS_ON_STACK);
    807 
    808   // Similar to LoadFloatOperand but assumes that both operands are smis.
    809   // Expects operands in edx, eax.
    810   static void LoadFloatSmis(MacroAssembler* masm, Register scratch);
    811 
    812   // Test if operands are smi or number objects (fp). Requirements:
    813   // operand_1 in eax, operand_2 in edx; falls through on float
    814   // operands, jumps to the non_float label otherwise.
    815   static void CheckFloatOperands(MacroAssembler* masm,
    816                                  Label* non_float,
    817                                  Register scratch);
    818   // Takes the operands in edx and eax and loads them as integers in eax
    819   // and ecx.
    820   static void LoadAsIntegers(MacroAssembler* masm,
    821                              bool use_sse3,
    822                              Label* operand_conversion_failure);
    823   // Test if operands are smis or heap numbers and load them
    824   // into xmm0 and xmm1 if they are. Operands are in edx and eax.
    825   // Leaves operands unchanged.
    826   static void LoadSSE2Operands(MacroAssembler* masm);
    827   // Test if operands are numbers (smi or HeapNumber objects), and load
    828   // them into xmm0 and xmm1 if they are.  Jump to label not_numbers if
    829   // either operand is not a number.  Operands are in edx and eax.
    830   // Leaves operands unchanged.
    831   static void LoadSSE2Operands(MacroAssembler* masm, Label* not_numbers);
    832 
    833   // Similar to LoadSSE2Operands but assumes that both operands are smis.
    834   // Expects operands in edx, eax.
    835   static void LoadSSE2Smis(MacroAssembler* masm, Register scratch);
    836 };
    837 
    838 
    839 const char* GenericBinaryOpStub::GetName() {
    840   if (name_ != NULL) return name_;
    841   const int kMaxNameLength = 100;
    842   name_ = Bootstrapper::AllocateAutoDeletedArray(kMaxNameLength);
    843   if (name_ == NULL) return "OOM";
    844   const char* op_name = Token::Name(op_);
    845   const char* overwrite_name;
    846   switch (mode_) {
    847     case NO_OVERWRITE: overwrite_name = "Alloc"; break;
    848     case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
    849     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
    850     default: overwrite_name = "UnknownOverwrite"; break;
    851   }
    852 
    853   OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
    854                "GenericBinaryOpStub_%s_%s%s_%s%s_%s",
    855                op_name,
    856                overwrite_name,
    857                (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "",
    858                args_in_registers_ ? "RegArgs" : "StackArgs",
    859                args_reversed_ ? "_R" : "",
    860                NumberInfo::ToString(operands_type_));
    861   return name_;
    862 }
    863 
    864 
    865 // Call the specialized stub for a binary operation.
    866 class DeferredInlineBinaryOperation: public DeferredCode {
    867  public:
    868   DeferredInlineBinaryOperation(Token::Value op,
    869                                 Register dst,
    870                                 Register left,
    871                                 Register right,
    872                                 OverwriteMode mode)
    873       : op_(op), dst_(dst), left_(left), right_(right), mode_(mode) {
    874     set_comment("[ DeferredInlineBinaryOperation");
    875   }
    876 
    877   virtual void Generate();
    878 
    879  private:
    880   Token::Value op_;
    881   Register dst_;
    882   Register left_;
    883   Register right_;
    884   OverwriteMode mode_;
    885 };
    886 
    887 
    888 void DeferredInlineBinaryOperation::Generate() {
    889   Label done;
    890   if (CpuFeatures::IsSupported(SSE2) && ((op_ == Token::ADD) ||
    891       (op_ ==Token::SUB) ||
    892       (op_ == Token::MUL) ||
    893       (op_ == Token::DIV))) {
    894     CpuFeatures::Scope use_sse2(SSE2);
    895     Label call_runtime, after_alloc_failure;
    896     Label left_smi, right_smi, load_right, do_op;
    897     __ test(left_, Immediate(kSmiTagMask));
    898     __ j(zero, &left_smi);
    899     __ cmp(FieldOperand(left_, HeapObject::kMapOffset),
    900            Factory::heap_number_map());
    901     __ j(not_equal, &call_runtime);
    902     __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset));
    903     if (mode_ == OVERWRITE_LEFT) {
    904       __ mov(dst_, left_);
    905     }
    906     __ jmp(&load_right);
    907 
    908     __ bind(&left_smi);
    909     __ SmiUntag(left_);
    910     __ cvtsi2sd(xmm0, Operand(left_));
    911     __ SmiTag(left_);
    912     if (mode_ == OVERWRITE_LEFT) {
    913       Label alloc_failure;
    914       __ push(left_);
    915       __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure);
    916       __ pop(left_);
    917     }
    918 
    919     __ bind(&load_right);
    920     __ test(right_, Immediate(kSmiTagMask));
    921     __ j(zero, &right_smi);
    922     __ cmp(FieldOperand(right_, HeapObject::kMapOffset),
    923            Factory::heap_number_map());
    924     __ j(not_equal, &call_runtime);
    925     __ movdbl(xmm1, FieldOperand(right_, HeapNumber::kValueOffset));
    926     if (mode_ == OVERWRITE_RIGHT) {
    927       __ mov(dst_, right_);
    928     } else if (mode_ == NO_OVERWRITE) {
    929       Label alloc_failure;
    930       __ push(left_);
    931       __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure);
    932       __ pop(left_);
    933     }
    934     __ jmp(&do_op);
    935 
    936     __ bind(&right_smi);
    937     __ SmiUntag(right_);
    938     __ cvtsi2sd(xmm1, Operand(right_));
    939     __ SmiTag(right_);
    940     if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) {
    941       Label alloc_failure;
    942       __ push(left_);
    943       __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure);
    944       __ pop(left_);
    945     }
    946 
    947     __ bind(&do_op);
    948     switch (op_) {
    949       case Token::ADD: __ addsd(xmm0, xmm1); break;
    950       case Token::SUB: __ subsd(xmm0, xmm1); break;
    951       case Token::MUL: __ mulsd(xmm0, xmm1); break;
    952       case Token::DIV: __ divsd(xmm0, xmm1); break;
    953       default: UNREACHABLE();
    954     }
    955     __ movdbl(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0);
    956     __ jmp(&done);
    957 
    958     __ bind(&after_alloc_failure);
    959     __ pop(left_);
    960     __ bind(&call_runtime);
    961   }
    962   GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB);
    963   stub.GenerateCall(masm_, left_, right_);
    964   if (!dst_.is(eax)) __ mov(dst_, eax);
    965   __ bind(&done);
    966 }
    967 
    968 
    969 void CodeGenerator::GenericBinaryOperation(Token::Value op,
    970                                            StaticType* type,
    971                                            OverwriteMode overwrite_mode) {
    972   Comment cmnt(masm_, "[ BinaryOperation");
    973   Comment cmnt_token(masm_, Token::String(op));
    974 
    975   if (op == Token::COMMA) {
    976     // Simply discard left value.
    977     frame_->Nip(1);
    978     return;
    979   }
    980 
    981   Result right = frame_->Pop();
    982   Result left = frame_->Pop();
    983 
    984   if (op == Token::ADD) {
    985     bool left_is_string = left.is_constant() && left.handle()->IsString();
    986     bool right_is_string = right.is_constant() && right.handle()->IsString();
    987     if (left_is_string || right_is_string) {
    988       frame_->Push(&left);
    989       frame_->Push(&right);
    990       Result answer;
    991       if (left_is_string) {
    992         if (right_is_string) {
    993           // TODO(lrn): if both are constant strings
    994           // -- do a compile time cons, if allocation during codegen is allowed.
    995           answer = frame_->CallRuntime(Runtime::kStringAdd, 2);
    996         } else {
    997           answer =
    998             frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2);
    999         }
   1000       } else if (right_is_string) {
   1001         answer =
   1002           frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
   1003       }
   1004       frame_->Push(&answer);
   1005       return;
   1006     }
   1007     // Neither operand is known to be a string.
   1008   }
   1009 
   1010   bool left_is_smi_constant = left.is_constant() && left.handle()->IsSmi();
   1011   bool left_is_non_smi_constant = left.is_constant() && !left.handle()->IsSmi();
   1012   bool right_is_smi_constant = right.is_constant() && right.handle()->IsSmi();
   1013   bool right_is_non_smi_constant =
   1014       right.is_constant() && !right.handle()->IsSmi();
   1015 
   1016   if (left_is_smi_constant && right_is_smi_constant) {
   1017     // Compute the constant result at compile time, and leave it on the frame.
   1018     int left_int = Smi::cast(*left.handle())->value();
   1019     int right_int = Smi::cast(*right.handle())->value();
   1020     if (FoldConstantSmis(op, left_int, right_int)) return;
   1021   }
   1022 
   1023   // Get number type of left and right sub-expressions.
   1024   NumberInfo::Type operands_type =
   1025       NumberInfo::Combine(left.number_info(), right.number_info());
   1026 
   1027   Result answer;
   1028   if (left_is_non_smi_constant || right_is_non_smi_constant) {
   1029     // Go straight to the slow case, with no smi code.
   1030     GenericBinaryOpStub stub(op,
   1031                              overwrite_mode,
   1032                              NO_SMI_CODE_IN_STUB,
   1033                              operands_type);
   1034     answer = stub.GenerateCall(masm_, frame_, &left, &right);
   1035   } else if (right_is_smi_constant) {
   1036     answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
   1037                                         type, false, overwrite_mode);
   1038   } else if (left_is_smi_constant) {
   1039     answer = ConstantSmiBinaryOperation(op, &right, left.handle(),
   1040                                         type, true, overwrite_mode);
   1041   } else {
   1042     // Set the flags based on the operation, type and loop nesting level.
   1043     // Bit operations always assume they likely operate on Smis. Still only
   1044     // generate the inline Smi check code if this operation is part of a loop.
   1045     // For all other operations only inline the Smi check code for likely smis
   1046     // if the operation is part of a loop.
   1047     if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) {
   1048       answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
   1049     } else {
   1050       GenericBinaryOpStub stub(op,
   1051                                overwrite_mode,
   1052                                NO_GENERIC_BINARY_FLAGS,
   1053                                operands_type);
   1054       answer = stub.GenerateCall(masm_, frame_, &left, &right);
   1055     }
   1056   }
   1057 
   1058   // Set NumberInfo of result according to the operation performed.
   1059   // Rely on the fact that smis have a 31 bit payload on ia32.
   1060   ASSERT(kSmiValueSize == 31);
   1061   NumberInfo::Type result_type = NumberInfo::kUnknown;
   1062   switch (op) {
   1063     case Token::COMMA:
   1064       result_type = right.number_info();
   1065       break;
   1066     case Token::OR:
   1067     case Token::AND:
   1068       // Result type can be either of the two input types.
   1069       result_type = operands_type;
   1070       break;
   1071     case Token::BIT_OR:
   1072     case Token::BIT_XOR:
   1073     case Token::BIT_AND:
   1074       // Result is always a number. Smi property of inputs is preserved.
   1075       result_type = (operands_type == NumberInfo::kSmi)
   1076           ? NumberInfo::kSmi
   1077           : NumberInfo::kNumber;
   1078       break;
   1079     case Token::SAR:
   1080       // Result is a smi if we shift by a constant >= 1, otherwise a number.
   1081       result_type = (right.is_constant() && right.handle()->IsSmi()
   1082                      && Smi::cast(*right.handle())->value() >= 1)
   1083           ? NumberInfo::kSmi
   1084           : NumberInfo::kNumber;
   1085       break;
   1086     case Token::SHR:
   1087       // Result is a smi if we shift by a constant >= 2, otherwise a number.
   1088       result_type = (right.is_constant() && right.handle()->IsSmi()
   1089                      && Smi::cast(*right.handle())->value() >= 2)
   1090           ? NumberInfo::kSmi
   1091           : NumberInfo::kNumber;
   1092       break;
   1093     case Token::ADD:
   1094       // Result could be a string or a number. Check types of inputs.
   1095       result_type = NumberInfo::IsNumber(operands_type)
   1096           ? NumberInfo::kNumber
   1097           : NumberInfo::kUnknown;
   1098       break;
   1099     case Token::SHL:
   1100     case Token::SUB:
   1101     case Token::MUL:
   1102     case Token::DIV:
   1103     case Token::MOD:
   1104       // Result is always a number.
   1105       result_type = NumberInfo::kNumber;
   1106       break;
   1107     default:
   1108       UNREACHABLE();
   1109   }
   1110   answer.set_number_info(result_type);
   1111   frame_->Push(&answer);
   1112 }
   1113 
   1114 
   1115 bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) {
   1116   Object* answer_object = Heap::undefined_value();
   1117   switch (op) {
   1118     case Token::ADD:
   1119       if (Smi::IsValid(left + right)) {
   1120         answer_object = Smi::FromInt(left + right);
   1121       }
   1122       break;
   1123     case Token::SUB:
   1124       if (Smi::IsValid(left - right)) {
   1125         answer_object = Smi::FromInt(left - right);
   1126       }
   1127       break;
   1128     case Token::MUL: {
   1129         double answer = static_cast<double>(left) * right;
   1130         if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) {
   1131           // If the product is zero and the non-zero factor is negative,
   1132           // the spec requires us to return floating point negative zero.
   1133           if (answer != 0 || (left >= 0 && right >= 0)) {
   1134             answer_object = Smi::FromInt(static_cast<int>(answer));
   1135           }
   1136         }
   1137       }
   1138       break;
   1139     case Token::DIV:
   1140     case Token::MOD:
   1141       break;
   1142     case Token::BIT_OR:
   1143       answer_object = Smi::FromInt(left | right);
   1144       break;
   1145     case Token::BIT_AND:
   1146       answer_object = Smi::FromInt(left & right);
   1147       break;
   1148     case Token::BIT_XOR:
   1149       answer_object = Smi::FromInt(left ^ right);
   1150       break;
   1151 
   1152     case Token::SHL: {
   1153         int shift_amount = right & 0x1F;
   1154         if (Smi::IsValid(left << shift_amount)) {
   1155           answer_object = Smi::FromInt(left << shift_amount);
   1156         }
   1157         break;
   1158       }
   1159     case Token::SHR: {
   1160         int shift_amount = right & 0x1F;
   1161         unsigned int unsigned_left = left;
   1162         unsigned_left >>= shift_amount;
   1163         if (unsigned_left <= static_cast<unsigned int>(Smi::kMaxValue)) {
   1164           answer_object = Smi::FromInt(unsigned_left);
   1165         }
   1166         break;
   1167       }
   1168     case Token::SAR: {
   1169         int shift_amount = right & 0x1F;
   1170         unsigned int unsigned_left = left;
   1171         if (left < 0) {
   1172           // Perform arithmetic shift of a negative number by
   1173           // complementing number, logical shifting, complementing again.
   1174           unsigned_left = ~unsigned_left;
   1175           unsigned_left >>= shift_amount;
   1176           unsigned_left = ~unsigned_left;
   1177         } else {
   1178           unsigned_left >>= shift_amount;
   1179         }
   1180         ASSERT(Smi::IsValid(unsigned_left));  // Converted to signed.
   1181         answer_object = Smi::FromInt(unsigned_left);  // Converted to signed.
   1182         break;
   1183       }
   1184     default:
   1185       UNREACHABLE();
   1186       break;
   1187   }
   1188   if (answer_object == Heap::undefined_value()) {
   1189     return false;
   1190   }
   1191   frame_->Push(Handle<Object>(answer_object));
   1192   return true;
   1193 }
   1194 
   1195 
   1196 // Implements a binary operation using a deferred code object and some
   1197 // inline code to operate on smis quickly.
   1198 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
   1199                                                Result* left,
   1200                                                Result* right,
   1201                                                OverwriteMode overwrite_mode) {
   1202   Result answer;
   1203   // Special handling of div and mod because they use fixed registers.
   1204   if (op == Token::DIV || op == Token::MOD) {
   1205     // We need eax as the quotient register, edx as the remainder
   1206     // register, neither left nor right in eax or edx, and left copied
   1207     // to eax.
   1208     Result quotient;
   1209     Result remainder;
   1210     bool left_is_in_eax = false;
   1211     // Step 1: get eax for quotient.
   1212     if ((left->is_register() && left->reg().is(eax)) ||
   1213         (right->is_register() && right->reg().is(eax))) {
   1214       // One or both is in eax.  Use a fresh non-edx register for
   1215       // them.
   1216       Result fresh = allocator_->Allocate();
   1217       ASSERT(fresh.is_valid());
   1218       if (fresh.reg().is(edx)) {
   1219         remainder = fresh;
   1220         fresh = allocator_->Allocate();
   1221         ASSERT(fresh.is_valid());
   1222       }
   1223       if (left->is_register() && left->reg().is(eax)) {
   1224         quotient = *left;
   1225         *left = fresh;
   1226         left_is_in_eax = true;
   1227       }
   1228       if (right->is_register() && right->reg().is(eax)) {
   1229         quotient = *right;
   1230         *right = fresh;
   1231       }
   1232       __ mov(fresh.reg(), eax);
   1233     } else {
   1234       // Neither left nor right is in eax.
   1235       quotient = allocator_->Allocate(eax);
   1236     }
   1237     ASSERT(quotient.is_register() && quotient.reg().is(eax));
   1238     ASSERT(!(left->is_register() && left->reg().is(eax)));
   1239     ASSERT(!(right->is_register() && right->reg().is(eax)));
   1240 
   1241     // Step 2: get edx for remainder if necessary.
   1242     if (!remainder.is_valid()) {
   1243       if ((left->is_register() && left->reg().is(edx)) ||
   1244           (right->is_register() && right->reg().is(edx))) {
   1245         Result fresh = allocator_->Allocate();
   1246         ASSERT(fresh.is_valid());
   1247         if (left->is_register() && left->reg().is(edx)) {
   1248           remainder = *left;
   1249           *left = fresh;
   1250         }
   1251         if (right->is_register() && right->reg().is(edx)) {
   1252           remainder = *right;
   1253           *right = fresh;
   1254         }
   1255         __ mov(fresh.reg(), edx);
   1256       } else {
   1257         // Neither left nor right is in edx.
   1258         remainder = allocator_->Allocate(edx);
   1259       }
   1260     }
   1261     ASSERT(remainder.is_register() && remainder.reg().is(edx));
   1262     ASSERT(!(left->is_register() && left->reg().is(edx)));
   1263     ASSERT(!(right->is_register() && right->reg().is(edx)));
   1264 
   1265     left->ToRegister();
   1266     right->ToRegister();
   1267     frame_->Spill(eax);
   1268     frame_->Spill(edx);
   1269 
   1270     // Check that left and right are smi tagged.
   1271     DeferredInlineBinaryOperation* deferred =
   1272         new DeferredInlineBinaryOperation(op,
   1273                                           (op == Token::DIV) ? eax : edx,
   1274                                           left->reg(),
   1275                                           right->reg(),
   1276                                           overwrite_mode);
   1277     if (left->reg().is(right->reg())) {
   1278       __ test(left->reg(), Immediate(kSmiTagMask));
   1279     } else {
   1280       // Use the quotient register as a scratch for the tag check.
   1281       if (!left_is_in_eax) __ mov(eax, left->reg());
   1282       left_is_in_eax = false;  // About to destroy the value in eax.
   1283       __ or_(eax, Operand(right->reg()));
   1284       ASSERT(kSmiTag == 0);  // Adjust test if not the case.
   1285       __ test(eax, Immediate(kSmiTagMask));
   1286     }
   1287     deferred->Branch(not_zero);
   1288 
   1289     if (!left_is_in_eax) __ mov(eax, left->reg());
   1290     // Sign extend eax into edx:eax.
   1291     __ cdq();
   1292     // Check for 0 divisor.
   1293     __ test(right->reg(), Operand(right->reg()));
   1294     deferred->Branch(zero);
   1295     // Divide edx:eax by the right operand.
   1296     __ idiv(right->reg());
   1297 
   1298     // Complete the operation.
   1299     if (op == Token::DIV) {
   1300       // Check for negative zero result.  If result is zero, and divisor
   1301       // is negative, return a floating point negative zero.  The
   1302       // virtual frame is unchanged in this block, so local control flow
   1303       // can use a Label rather than a JumpTarget.
   1304       Label non_zero_result;
   1305       __ test(left->reg(), Operand(left->reg()));
   1306       __ j(not_zero, &non_zero_result);
   1307       __ test(right->reg(), Operand(right->reg()));
   1308       deferred->Branch(negative);
   1309       __ bind(&non_zero_result);
   1310       // Check for the corner case of dividing the most negative smi by
   1311       // -1. We cannot use the overflow flag, since it is not set by
   1312       // idiv instruction.
   1313       ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
   1314       __ cmp(eax, 0x40000000);
   1315       deferred->Branch(equal);
   1316       // Check that the remainder is zero.
   1317       __ test(edx, Operand(edx));
   1318       deferred->Branch(not_zero);
   1319       // Tag the result and store it in the quotient register.
   1320       __ SmiTag(eax);
   1321       deferred->BindExit();
   1322       left->Unuse();
   1323       right->Unuse();
   1324       answer = quotient;
   1325     } else {
   1326       ASSERT(op == Token::MOD);
   1327       // Check for a negative zero result.  If the result is zero, and
   1328       // the dividend is negative, return a floating point negative
   1329       // zero.  The frame is unchanged in this block, so local control
   1330       // flow can use a Label rather than a JumpTarget.
   1331       Label non_zero_result;
   1332       __ test(edx, Operand(edx));
   1333       __ j(not_zero, &non_zero_result, taken);
   1334       __ test(left->reg(), Operand(left->reg()));
   1335       deferred->Branch(negative);
   1336       __ bind(&non_zero_result);
   1337       deferred->BindExit();
   1338       left->Unuse();
   1339       right->Unuse();
   1340       answer = remainder;
   1341     }
   1342     ASSERT(answer.is_valid());
   1343     return answer;
   1344   }
   1345 
   1346   // Special handling of shift operations because they use fixed
   1347   // registers.
   1348   if (op == Token::SHL || op == Token::SHR || op == Token::SAR) {
   1349     // Move left out of ecx if necessary.
   1350     if (left->is_register() && left->reg().is(ecx)) {
   1351       *left = allocator_->Allocate();
   1352       ASSERT(left->is_valid());
   1353       __ mov(left->reg(), ecx);
   1354     }
   1355     right->ToRegister(ecx);
   1356     left->ToRegister();
   1357     ASSERT(left->is_register() && !left->reg().is(ecx));
   1358     ASSERT(right->is_register() && right->reg().is(ecx));
   1359 
   1360     // We will modify right, it must be spilled.
   1361     frame_->Spill(ecx);
   1362 
   1363     // Use a fresh answer register to avoid spilling the left operand.
   1364     answer = allocator_->Allocate();
   1365     ASSERT(answer.is_valid());
   1366     // Check that both operands are smis using the answer register as a
   1367     // temporary.
   1368     DeferredInlineBinaryOperation* deferred =
   1369         new DeferredInlineBinaryOperation(op,
   1370                                           answer.reg(),
   1371                                           left->reg(),
   1372                                           ecx,
   1373                                           overwrite_mode);
   1374     __ mov(answer.reg(), left->reg());
   1375     __ or_(answer.reg(), Operand(ecx));
   1376     __ test(answer.reg(), Immediate(kSmiTagMask));
   1377     deferred->Branch(not_zero);
   1378 
   1379     // Untag both operands.
   1380     __ mov(answer.reg(), left->reg());
   1381     __ SmiUntag(answer.reg());
   1382     __ SmiUntag(ecx);
   1383     // Perform the operation.
   1384     switch (op) {
   1385       case Token::SAR:
   1386         __ sar_cl(answer.reg());
   1387         // No checks of result necessary
   1388         break;
   1389       case Token::SHR: {
   1390         Label result_ok;
   1391         __ shr_cl(answer.reg());
   1392         // Check that the *unsigned* result fits in a smi.  Neither of
   1393         // the two high-order bits can be set:
   1394         //  * 0x80000000: high bit would be lost when smi tagging.
   1395         //  * 0x40000000: this number would convert to negative when smi
   1396         //    tagging.
   1397         // These two cases can only happen with shifts by 0 or 1 when
   1398         // handed a valid smi.  If the answer cannot be represented by a
   1399         // smi, restore the left and right arguments, and jump to slow
   1400         // case.  The low bit of the left argument may be lost, but only
   1401         // in a case where it is dropped anyway.
   1402         __ test(answer.reg(), Immediate(0xc0000000));
   1403         __ j(zero, &result_ok);
   1404         __ SmiTag(ecx);
   1405         deferred->Jump();
   1406         __ bind(&result_ok);
   1407         break;
   1408       }
   1409       case Token::SHL: {
   1410         Label result_ok;
   1411         __ shl_cl(answer.reg());
   1412         // Check that the *signed* result fits in a smi.
   1413         __ cmp(answer.reg(), 0xc0000000);
   1414         __ j(positive, &result_ok);
   1415         __ SmiTag(ecx);
   1416         deferred->Jump();
   1417         __ bind(&result_ok);
   1418         break;
   1419       }
   1420       default:
   1421         UNREACHABLE();
   1422     }
   1423     // Smi-tag the result in answer.
   1424     __ SmiTag(answer.reg());
   1425     deferred->BindExit();
   1426     left->Unuse();
   1427     right->Unuse();
   1428     ASSERT(answer.is_valid());
   1429     return answer;
   1430   }
   1431 
   1432   // Handle the other binary operations.
   1433   left->ToRegister();
   1434   right->ToRegister();
   1435   // A newly allocated register answer is used to hold the answer.  The
   1436   // registers containing left and right are not modified so they don't
   1437   // need to be spilled in the fast case.
   1438   answer = allocator_->Allocate();
   1439   ASSERT(answer.is_valid());
   1440 
   1441   // Perform the smi tag check.
   1442   DeferredInlineBinaryOperation* deferred =
   1443       new DeferredInlineBinaryOperation(op,
   1444                                         answer.reg(),
   1445                                         left->reg(),
   1446                                         right->reg(),
   1447                                         overwrite_mode);
   1448   if (left->reg().is(right->reg())) {
   1449     __ test(left->reg(), Immediate(kSmiTagMask));
   1450   } else {
   1451     __ mov(answer.reg(), left->reg());
   1452     __ or_(answer.reg(), Operand(right->reg()));
   1453     ASSERT(kSmiTag == 0);  // Adjust test if not the case.
   1454     __ test(answer.reg(), Immediate(kSmiTagMask));
   1455   }
   1456   deferred->Branch(not_zero);
   1457   __ mov(answer.reg(), left->reg());
   1458   switch (op) {
   1459     case Token::ADD:
   1460       __ add(answer.reg(), Operand(right->reg()));
   1461       deferred->Branch(overflow);
   1462       break;
   1463 
   1464     case Token::SUB:
   1465       __ sub(answer.reg(), Operand(right->reg()));
   1466       deferred->Branch(overflow);
   1467       break;
   1468 
   1469     case Token::MUL: {
   1470       // If the smi tag is 0 we can just leave the tag on one operand.
   1471       ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
   1472       // Remove smi tag from the left operand (but keep sign).
   1473       // Left-hand operand has been copied into answer.
   1474       __ SmiUntag(answer.reg());
   1475       // Do multiplication of smis, leaving result in answer.
   1476       __ imul(answer.reg(), Operand(right->reg()));
   1477       // Go slow on overflows.
   1478       deferred->Branch(overflow);
   1479       // Check for negative zero result.  If product is zero, and one
   1480       // argument is negative, go to slow case.  The frame is unchanged
   1481       // in this block, so local control flow can use a Label rather
   1482       // than a JumpTarget.
   1483       Label non_zero_result;
   1484       __ test(answer.reg(), Operand(answer.reg()));
   1485       __ j(not_zero, &non_zero_result, taken);
   1486       __ mov(answer.reg(), left->reg());
   1487       __ or_(answer.reg(), Operand(right->reg()));
   1488       deferred->Branch(negative);
   1489       __ xor_(answer.reg(), Operand(answer.reg()));  // Positive 0 is correct.
   1490       __ bind(&non_zero_result);
   1491       break;
   1492     }
   1493 
   1494     case Token::BIT_OR:
   1495       __ or_(answer.reg(), Operand(right->reg()));
   1496       break;
   1497 
   1498     case Token::BIT_AND:
   1499       __ and_(answer.reg(), Operand(right->reg()));
   1500       break;
   1501 
   1502     case Token::BIT_XOR:
   1503       __ xor_(answer.reg(), Operand(right->reg()));
   1504       break;
   1505 
   1506     default:
   1507       UNREACHABLE();
   1508       break;
   1509   }
   1510   deferred->BindExit();
   1511   left->Unuse();
   1512   right->Unuse();
   1513   ASSERT(answer.is_valid());
   1514   return answer;
   1515 }
   1516 
   1517 
   1518 // Call the appropriate binary operation stub to compute src op value
   1519 // and leave the result in dst.
   1520 class DeferredInlineSmiOperation: public DeferredCode {
   1521  public:
   1522   DeferredInlineSmiOperation(Token::Value op,
   1523                              Register dst,
   1524                              Register src,
   1525                              Smi* value,
   1526                              OverwriteMode overwrite_mode)
   1527       : op_(op),
   1528         dst_(dst),
   1529         src_(src),
   1530         value_(value),
   1531         overwrite_mode_(overwrite_mode) {
   1532     set_comment("[ DeferredInlineSmiOperation");
   1533   }
   1534 
   1535   virtual void Generate();
   1536 
   1537  private:
   1538   Token::Value op_;
   1539   Register dst_;
   1540   Register src_;
   1541   Smi* value_;
   1542   OverwriteMode overwrite_mode_;
   1543 };
   1544 
   1545 
   1546 void DeferredInlineSmiOperation::Generate() {
   1547   // For mod we don't generate all the Smi code inline.
   1548   GenericBinaryOpStub stub(
   1549       op_,
   1550       overwrite_mode_,
   1551       (op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB);
   1552   stub.GenerateCall(masm_, src_, value_);
   1553   if (!dst_.is(eax)) __ mov(dst_, eax);
   1554 }
   1555 
   1556 
   1557 // Call the appropriate binary operation stub to compute value op src
   1558 // and leave the result in dst.
   1559 class DeferredInlineSmiOperationReversed: public DeferredCode {
   1560  public:
   1561   DeferredInlineSmiOperationReversed(Token::Value op,
   1562                                      Register dst,
   1563                                      Smi* value,
   1564                                      Register src,
   1565                                      OverwriteMode overwrite_mode)
   1566       : op_(op),
   1567         dst_(dst),
   1568         value_(value),
   1569         src_(src),
   1570         overwrite_mode_(overwrite_mode) {
   1571     set_comment("[ DeferredInlineSmiOperationReversed");
   1572   }
   1573 
   1574   virtual void Generate();
   1575 
   1576  private:
   1577   Token::Value op_;
   1578   Register dst_;
   1579   Smi* value_;
   1580   Register src_;
   1581   OverwriteMode overwrite_mode_;
   1582 };
   1583 
   1584 
   1585 void DeferredInlineSmiOperationReversed::Generate() {
   1586   GenericBinaryOpStub igostub(op_, overwrite_mode_, NO_SMI_CODE_IN_STUB);
   1587   igostub.GenerateCall(masm_, value_, src_);
   1588   if (!dst_.is(eax)) __ mov(dst_, eax);
   1589 }
   1590 
   1591 
   1592 // The result of src + value is in dst.  It either overflowed or was not
   1593 // smi tagged.  Undo the speculative addition and call the appropriate
   1594 // specialized stub for add.  The result is left in dst.
   1595 class DeferredInlineSmiAdd: public DeferredCode {
   1596  public:
   1597   DeferredInlineSmiAdd(Register dst,
   1598                        Smi* value,
   1599                        OverwriteMode overwrite_mode)
   1600       : dst_(dst), value_(value), overwrite_mode_(overwrite_mode) {
   1601     set_comment("[ DeferredInlineSmiAdd");
   1602   }
   1603 
   1604   virtual void Generate();
   1605 
   1606  private:
   1607   Register dst_;
   1608   Smi* value_;
   1609   OverwriteMode overwrite_mode_;
   1610 };
   1611 
   1612 
   1613 void DeferredInlineSmiAdd::Generate() {
   1614   // Undo the optimistic add operation and call the shared stub.
   1615   __ sub(Operand(dst_), Immediate(value_));
   1616   GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, NO_SMI_CODE_IN_STUB);
   1617   igostub.GenerateCall(masm_, dst_, value_);
   1618   if (!dst_.is(eax)) __ mov(dst_, eax);
   1619 }
   1620 
   1621 
   1622 // The result of value + src is in dst.  It either overflowed or was not
   1623 // smi tagged.  Undo the speculative addition and call the appropriate
   1624 // specialized stub for add.  The result is left in dst.
   1625 class DeferredInlineSmiAddReversed: public DeferredCode {
   1626  public:
   1627   DeferredInlineSmiAddReversed(Register dst,
   1628                                Smi* value,
   1629                                OverwriteMode overwrite_mode)
   1630       : dst_(dst), value_(value), overwrite_mode_(overwrite_mode) {
   1631     set_comment("[ DeferredInlineSmiAddReversed");
   1632   }
   1633 
   1634   virtual void Generate();
   1635 
   1636  private:
   1637   Register dst_;
   1638   Smi* value_;
   1639   OverwriteMode overwrite_mode_;
   1640 };
   1641 
   1642 
   1643 void DeferredInlineSmiAddReversed::Generate() {
   1644   // Undo the optimistic add operation and call the shared stub.
   1645   __ sub(Operand(dst_), Immediate(value_));
   1646   GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, NO_SMI_CODE_IN_STUB);
   1647   igostub.GenerateCall(masm_, value_, dst_);
   1648   if (!dst_.is(eax)) __ mov(dst_, eax);
   1649 }
   1650 
   1651 
   1652 // The result of src - value is in dst.  It either overflowed or was not
   1653 // smi tagged.  Undo the speculative subtraction and call the
   1654 // appropriate specialized stub for subtract.  The result is left in
   1655 // dst.
   1656 class DeferredInlineSmiSub: public DeferredCode {
   1657  public:
   1658   DeferredInlineSmiSub(Register dst,
   1659                        Smi* value,
   1660                        OverwriteMode overwrite_mode)
   1661       : dst_(dst), value_(value), overwrite_mode_(overwrite_mode) {
   1662     set_comment("[ DeferredInlineSmiSub");
   1663   }
   1664 
   1665   virtual void Generate();
   1666 
   1667  private:
   1668   Register dst_;
   1669   Smi* value_;
   1670   OverwriteMode overwrite_mode_;
   1671 };
   1672 
   1673 
   1674 void DeferredInlineSmiSub::Generate() {
   1675   // Undo the optimistic sub operation and call the shared stub.
   1676   __ add(Operand(dst_), Immediate(value_));
   1677   GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, NO_SMI_CODE_IN_STUB);
   1678   igostub.GenerateCall(masm_, dst_, value_);
   1679   if (!dst_.is(eax)) __ mov(dst_, eax);
   1680 }
   1681 
   1682 
   1683 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
   1684                                                  Result* operand,
   1685                                                  Handle<Object> value,
   1686                                                  StaticType* type,
   1687                                                  bool reversed,
   1688                                                  OverwriteMode overwrite_mode) {
   1689   // NOTE: This is an attempt to inline (a bit) more of the code for
   1690   // some possible smi operations (like + and -) when (at least) one
   1691   // of the operands is a constant smi.
   1692   // Consumes the argument "operand".
   1693   // TODO(199): Optimize some special cases of operations involving a
   1694   // smi literal (multiply by 2, shift by 0, etc.).
   1695   if (IsUnsafeSmi(value)) {
   1696     Result unsafe_operand(value);
   1697     if (reversed) {
   1698       return LikelySmiBinaryOperation(op, &unsafe_operand, operand,
   1699                                       overwrite_mode);
   1700     } else {
   1701       return LikelySmiBinaryOperation(op, operand, &unsafe_operand,
   1702                                       overwrite_mode);
   1703     }
   1704   }
   1705 
   1706   // Get the literal value.
   1707   Smi* smi_value = Smi::cast(*value);
   1708   int int_value = smi_value->value();
   1709 
   1710   Result answer;
   1711   switch (op) {
   1712     case Token::ADD: {
   1713       operand->ToRegister();
   1714       frame_->Spill(operand->reg());
   1715 
   1716       // Optimistically add.  Call the specialized add stub if the
   1717       // result is not a smi or overflows.
   1718       DeferredCode* deferred = NULL;
   1719       if (reversed) {
   1720         deferred = new DeferredInlineSmiAddReversed(operand->reg(),
   1721                                                     smi_value,
   1722                                                     overwrite_mode);
   1723       } else {
   1724         deferred = new DeferredInlineSmiAdd(operand->reg(),
   1725                                             smi_value,
   1726                                             overwrite_mode);
   1727       }
   1728       __ add(Operand(operand->reg()), Immediate(value));
   1729       deferred->Branch(overflow);
   1730       __ test(operand->reg(), Immediate(kSmiTagMask));
   1731       deferred->Branch(not_zero);
   1732       deferred->BindExit();
   1733       answer = *operand;
   1734       break;
   1735     }
   1736 
   1737     case Token::SUB: {
   1738       DeferredCode* deferred = NULL;
   1739       if (reversed) {
   1740         // The reversed case is only hit when the right operand is not a
   1741         // constant.
   1742         ASSERT(operand->is_register());
   1743         answer = allocator()->Allocate();
   1744         ASSERT(answer.is_valid());
   1745         __ Set(answer.reg(), Immediate(value));
   1746         deferred = new DeferredInlineSmiOperationReversed(op,
   1747                                                           answer.reg(),
   1748                                                           smi_value,
   1749                                                           operand->reg(),
   1750                                                           overwrite_mode);
   1751         __ sub(answer.reg(), Operand(operand->reg()));
   1752       } else {
   1753         operand->ToRegister();
   1754         frame_->Spill(operand->reg());
   1755         answer = *operand;
   1756         deferred = new DeferredInlineSmiSub(operand->reg(),
   1757                                             smi_value,
   1758                                             overwrite_mode);
   1759         __ sub(Operand(operand->reg()), Immediate(value));
   1760       }
   1761       deferred->Branch(overflow);
   1762       __ test(answer.reg(), Immediate(kSmiTagMask));
   1763       deferred->Branch(not_zero);
   1764       deferred->BindExit();
   1765       operand->Unuse();
   1766       break;
   1767     }
   1768 
   1769     case Token::SAR:
   1770       if (reversed) {
   1771         Result constant_operand(value);
   1772         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
   1773                                           overwrite_mode);
   1774       } else {
   1775         // Only the least significant 5 bits of the shift value are used.
   1776         // In the slow case, this masking is done inside the runtime call.
   1777         int shift_value = int_value & 0x1f;
   1778         operand->ToRegister();
   1779         frame_->Spill(operand->reg());
   1780         DeferredInlineSmiOperation* deferred =
   1781             new DeferredInlineSmiOperation(op,
   1782                                            operand->reg(),
   1783                                            operand->reg(),
   1784                                            smi_value,
   1785                                            overwrite_mode);
   1786         __ test(operand->reg(), Immediate(kSmiTagMask));
   1787         deferred->Branch(not_zero);
   1788         if (shift_value > 0) {
   1789           __ sar(operand->reg(), shift_value);
   1790           __ and_(operand->reg(), ~kSmiTagMask);
   1791         }
   1792         deferred->BindExit();
   1793         answer = *operand;
   1794       }
   1795       break;
   1796 
   1797     case Token::SHR:
   1798       if (reversed) {
   1799         Result constant_operand(value);
   1800         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
   1801                                           overwrite_mode);
   1802       } else {
   1803         // Only the least significant 5 bits of the shift value are used.
   1804         // In the slow case, this masking is done inside the runtime call.
   1805         int shift_value = int_value & 0x1f;
   1806         operand->ToRegister();
   1807         answer = allocator()->Allocate();
   1808         ASSERT(answer.is_valid());
   1809         DeferredInlineSmiOperation* deferred =
   1810             new DeferredInlineSmiOperation(op,
   1811                                            answer.reg(),
   1812                                            operand->reg(),
   1813                                            smi_value,
   1814                                            overwrite_mode);
   1815         __ test(operand->reg(), Immediate(kSmiTagMask));
   1816         deferred->Branch(not_zero);
   1817         __ mov(answer.reg(), operand->reg());
   1818         __ SmiUntag(answer.reg());
   1819         __ shr(answer.reg(), shift_value);
   1820         // A negative Smi shifted right two is in the positive Smi range.
   1821         if (shift_value < 2) {
   1822           __ test(answer.reg(), Immediate(0xc0000000));
   1823           deferred->Branch(not_zero);
   1824         }
   1825         operand->Unuse();
   1826         __ SmiTag(answer.reg());
   1827         deferred->BindExit();
   1828       }
   1829       break;
   1830 
   1831     case Token::SHL:
   1832       if (reversed) {
   1833         Result right;
   1834         Result right_copy_in_ecx;
   1835 
   1836         // Make sure to get a copy of the right operand into ecx. This
   1837         // allows us to modify it without having to restore it in the
   1838         // deferred code.
   1839         operand->ToRegister();
   1840         if (operand->reg().is(ecx)) {
   1841           right = allocator()->Allocate();
   1842           __ mov(right.reg(), ecx);
   1843           frame_->Spill(ecx);
   1844           right_copy_in_ecx = *operand;
   1845         } else {
   1846           right_copy_in_ecx = allocator()->Allocate(ecx);
   1847           __ mov(ecx, operand->reg());
   1848           right = *operand;
   1849         }
   1850         operand->Unuse();
   1851 
   1852         answer = allocator()->Allocate();
   1853         DeferredInlineSmiOperationReversed* deferred =
   1854             new DeferredInlineSmiOperationReversed(op,
   1855                                                    answer.reg(),
   1856                                                    smi_value,
   1857                                                    right.reg(),
   1858                                                    overwrite_mode);
   1859         __ mov(answer.reg(), Immediate(int_value));
   1860         __ sar(ecx, kSmiTagSize);
   1861         deferred->Branch(carry);
   1862         __ shl_cl(answer.reg());
   1863         __ cmp(answer.reg(), 0xc0000000);
   1864         deferred->Branch(sign);
   1865         __ SmiTag(answer.reg());
   1866 
   1867         deferred->BindExit();
   1868       } else {
   1869         // Only the least significant 5 bits of the shift value are used.
   1870         // In the slow case, this masking is done inside the runtime call.
   1871         int shift_value = int_value & 0x1f;
   1872         operand->ToRegister();
   1873         if (shift_value == 0) {
   1874           // Spill operand so it can be overwritten in the slow case.
   1875           frame_->Spill(operand->reg());
   1876           DeferredInlineSmiOperation* deferred =
   1877               new DeferredInlineSmiOperation(op,
   1878                                              operand->reg(),
   1879                                              operand->reg(),
   1880                                              smi_value,
   1881                                              overwrite_mode);
   1882           __ test(operand->reg(), Immediate(kSmiTagMask));
   1883           deferred->Branch(not_zero);
   1884           deferred->BindExit();
   1885           answer = *operand;
   1886         } else {
   1887           // Use a fresh temporary for nonzero shift values.
   1888           answer = allocator()->Allocate();
   1889           ASSERT(answer.is_valid());
   1890           DeferredInlineSmiOperation* deferred =
   1891               new DeferredInlineSmiOperation(op,
   1892                                              answer.reg(),
   1893                                              operand->reg(),
   1894                                              smi_value,
   1895                                              overwrite_mode);
   1896           __ test(operand->reg(), Immediate(kSmiTagMask));
   1897           deferred->Branch(not_zero);
   1898           __ mov(answer.reg(), operand->reg());
   1899           ASSERT(kSmiTag == 0);  // adjust code if not the case
   1900           // We do no shifts, only the Smi conversion, if shift_value is 1.
   1901           if (shift_value > 1) {
   1902             __ shl(answer.reg(), shift_value - 1);
   1903           }
   1904           // Convert int result to Smi, checking that it is in int range.
   1905           ASSERT(kSmiTagSize == 1);  // adjust code if not the case
   1906           __ add(answer.reg(), Operand(answer.reg()));
   1907           deferred->Branch(overflow);
   1908           deferred->BindExit();
   1909           operand->Unuse();
   1910         }
   1911       }
   1912       break;
   1913 
   1914     case Token::BIT_OR:
   1915     case Token::BIT_XOR:
   1916     case Token::BIT_AND: {
   1917       operand->ToRegister();
   1918       frame_->Spill(operand->reg());
   1919       DeferredCode* deferred = NULL;
   1920       if (reversed) {
   1921         deferred = new DeferredInlineSmiOperationReversed(op,
   1922                                                           operand->reg(),
   1923                                                           smi_value,
   1924                                                           operand->reg(),
   1925                                                           overwrite_mode);
   1926       } else {
   1927         deferred =  new DeferredInlineSmiOperation(op,
   1928                                                    operand->reg(),
   1929                                                    operand->reg(),
   1930                                                    smi_value,
   1931                                                    overwrite_mode);
   1932       }
   1933       __ test(operand->reg(), Immediate(kSmiTagMask));
   1934       deferred->Branch(not_zero);
   1935       if (op == Token::BIT_AND) {
   1936         __ and_(Operand(operand->reg()), Immediate(value));
   1937       } else if (op == Token::BIT_XOR) {
   1938         if (int_value != 0) {
   1939           __ xor_(Operand(operand->reg()), Immediate(value));
   1940         }
   1941       } else {
   1942         ASSERT(op == Token::BIT_OR);
   1943         if (int_value != 0) {
   1944           __ or_(Operand(operand->reg()), Immediate(value));
   1945         }
   1946       }
   1947       deferred->BindExit();
   1948       answer = *operand;
   1949       break;
   1950     }
   1951 
   1952     case Token::DIV:
   1953       if (!reversed && int_value == 2) {
   1954         operand->ToRegister();
   1955         frame_->Spill(operand->reg());
   1956 
   1957         DeferredInlineSmiOperation* deferred =
   1958             new DeferredInlineSmiOperation(op,
   1959                                            operand->reg(),
   1960                                            operand->reg(),
   1961                                            smi_value,
   1962                                            overwrite_mode);
   1963         // Check that lowest log2(value) bits of operand are zero, and test
   1964         // smi tag at the same time.
   1965         ASSERT_EQ(0, kSmiTag);
   1966         ASSERT_EQ(1, kSmiTagSize);
   1967         __ test(operand->reg(), Immediate(3));
   1968         deferred->Branch(not_zero);  // Branch if non-smi or odd smi.
   1969         __ sar(operand->reg(), 1);
   1970         deferred->BindExit();
   1971         answer = *operand;
   1972       } else {
   1973         // Cannot fall through MOD to default case, so we duplicate the
   1974         // default case here.
   1975         Result constant_operand(value);
   1976         if (reversed) {
   1977           answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
   1978                                             overwrite_mode);
   1979         } else {
   1980           answer = LikelySmiBinaryOperation(op, operand, &constant_operand,
   1981                                             overwrite_mode);
   1982         }
   1983       }
   1984       break;
   1985     // Generate inline code for mod of powers of 2 and negative powers of 2.
   1986     case Token::MOD:
   1987       if (!reversed &&
   1988           int_value != 0 &&
   1989           (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) {
   1990         operand->ToRegister();
   1991         frame_->Spill(operand->reg());
   1992         DeferredCode* deferred = new DeferredInlineSmiOperation(op,
   1993                                                                 operand->reg(),
   1994                                                                 operand->reg(),
   1995                                                                 smi_value,
   1996                                                                 overwrite_mode);
   1997         // Check for negative or non-Smi left hand side.
   1998         __ test(operand->reg(), Immediate(kSmiTagMask | 0x80000000));
   1999         deferred->Branch(not_zero);
   2000         if (int_value < 0) int_value = -int_value;
   2001         if (int_value == 1) {
   2002           __ mov(operand->reg(), Immediate(Smi::FromInt(0)));
   2003         } else {
   2004           __ and_(operand->reg(), (int_value << kSmiTagSize) - 1);
   2005         }
   2006         deferred->BindExit();
   2007         answer = *operand;
   2008         break;
   2009       }
   2010       // Fall through if we did not find a power of 2 on the right hand side!
   2011 
   2012     default: {
   2013       Result constant_operand(value);
   2014       if (reversed) {
   2015         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
   2016                                           overwrite_mode);
   2017       } else {
   2018         answer = LikelySmiBinaryOperation(op, operand, &constant_operand,
   2019                                           overwrite_mode);
   2020       }
   2021       break;
   2022     }
   2023   }
   2024   ASSERT(answer.is_valid());
   2025   return answer;
   2026 }
   2027 
   2028 
   2029 static bool CouldBeNaN(const Result& result) {
   2030   if (!result.is_constant()) return true;
   2031   if (!result.handle()->IsHeapNumber()) return false;
   2032   return isnan(HeapNumber::cast(*result.handle())->value());
   2033 }
   2034 
   2035 
   2036 void CodeGenerator::Comparison(AstNode* node,
   2037                                Condition cc,
   2038                                bool strict,
   2039                                ControlDestination* dest) {
   2040   // Strict only makes sense for equality comparisons.
   2041   ASSERT(!strict || cc == equal);
   2042 
   2043   Result left_side;
   2044   Result right_side;
   2045   // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
   2046   if (cc == greater || cc == less_equal) {
   2047     cc = ReverseCondition(cc);
   2048     left_side = frame_->Pop();
   2049     right_side = frame_->Pop();
   2050   } else {
   2051     right_side = frame_->Pop();
   2052     left_side = frame_->Pop();
   2053   }
   2054   ASSERT(cc == less || cc == equal || cc == greater_equal);
   2055 
   2056   // If either side is a constant of some sort, we can probably optimize the
   2057   // comparison.
   2058   bool left_side_constant_smi = false;
   2059   bool left_side_constant_null = false;
   2060   bool left_side_constant_1_char_string = false;
   2061   if (left_side.is_constant()) {
   2062     left_side_constant_smi = left_side.handle()->IsSmi();
   2063     left_side_constant_null = left_side.handle()->IsNull();
   2064     left_side_constant_1_char_string =
   2065         (left_side.handle()->IsString() &&
   2066          (String::cast(*left_side.handle())->length() == 1));
   2067   }
   2068   bool right_side_constant_smi = false;
   2069   bool right_side_constant_null = false;
   2070   bool right_side_constant_1_char_string = false;
   2071   if (right_side.is_constant()) {
   2072     right_side_constant_smi = right_side.handle()->IsSmi();
   2073     right_side_constant_null = right_side.handle()->IsNull();
   2074     right_side_constant_1_char_string =
   2075         (right_side.handle()->IsString() &&
   2076          (String::cast(*right_side.handle())->length() == 1));
   2077   }
   2078 
   2079   if (left_side_constant_smi || right_side_constant_smi) {
   2080     if (left_side_constant_smi && right_side_constant_smi) {
   2081       // Trivial case, comparing two constants.
   2082       int left_value = Smi::cast(*left_side.handle())->value();
   2083       int right_value = Smi::cast(*right_side.handle())->value();
   2084       switch (cc) {
   2085         case less:
   2086           dest->Goto(left_value < right_value);
   2087           break;
   2088         case equal:
   2089           dest->Goto(left_value == right_value);
   2090           break;
   2091         case greater_equal:
   2092           dest->Goto(left_value >= right_value);
   2093           break;
   2094         default:
   2095           UNREACHABLE();
   2096       }
   2097     } else {
   2098       // Only one side is a constant Smi.
   2099       // If left side is a constant Smi, reverse the operands.
   2100       // Since one side is a constant Smi, conversion order does not matter.
   2101       if (left_side_constant_smi) {
   2102         Result temp = left_side;
   2103         left_side = right_side;
   2104         right_side = temp;
   2105         cc = ReverseCondition(cc);
   2106         // This may reintroduce greater or less_equal as the value of cc.
   2107         // CompareStub and the inline code both support all values of cc.
   2108       }
   2109       // Implement comparison against a constant Smi, inlining the case
   2110       // where both sides are Smis.
   2111       left_side.ToRegister();
   2112       Register left_reg = left_side.reg();
   2113       Handle<Object> right_val = right_side.handle();
   2114 
   2115       // Here we split control flow to the stub call and inlined cases
   2116       // before finally splitting it to the control destination.  We use
   2117       // a jump target and branching to duplicate the virtual frame at
   2118       // the first split.  We manually handle the off-frame references
   2119       // by reconstituting them on the non-fall-through path.
   2120       JumpTarget is_smi;
   2121       __ test(left_side.reg(), Immediate(kSmiTagMask));
   2122       is_smi.Branch(zero, taken);
   2123 
   2124       bool is_for_loop_compare = (node->AsCompareOperation() != NULL)
   2125           && node->AsCompareOperation()->is_for_loop_condition();
   2126       if (!is_for_loop_compare
   2127           && CpuFeatures::IsSupported(SSE2)
   2128           && right_val->IsSmi()) {
   2129         // Right side is a constant smi and left side has been checked
   2130         // not to be a smi.
   2131         CpuFeatures::Scope use_sse2(SSE2);
   2132         JumpTarget not_number;
   2133         __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
   2134                Immediate(Factory::heap_number_map()));
   2135         not_number.Branch(not_equal, &left_side);
   2136         __ movdbl(xmm1,
   2137                   FieldOperand(left_reg, HeapNumber::kValueOffset));
   2138         int value = Smi::cast(*right_val)->value();
   2139         if (value == 0) {
   2140           __ xorpd(xmm0, xmm0);
   2141         } else {
   2142           Result temp = allocator()->Allocate();
   2143           __ mov(temp.reg(), Immediate(value));
   2144           __ cvtsi2sd(xmm0, Operand(temp.reg()));
   2145           temp.Unuse();
   2146         }
   2147         __ comisd(xmm1, xmm0);
   2148         // Jump to builtin for NaN.
   2149         not_number.Branch(parity_even, &left_side);
   2150         left_side.Unuse();
   2151         Condition double_cc = cc;
   2152         switch (cc) {
   2153           case less:          double_cc = below;       break;
   2154           case equal:         double_cc = equal;       break;
   2155           case less_equal:    double_cc = below_equal; break;
   2156           case greater:       double_cc = above;       break;
   2157           case greater_equal: double_cc = above_equal; break;
   2158           default: UNREACHABLE();
   2159         }
   2160         dest->true_target()->Branch(double_cc);
   2161         dest->false_target()->Jump();
   2162         not_number.Bind(&left_side);
   2163       }
   2164 
   2165       // Setup and call the compare stub.
   2166       CompareStub stub(cc, strict, kCantBothBeNaN);
   2167       Result result = frame_->CallStub(&stub, &left_side, &right_side);
   2168       result.ToRegister();
   2169       __ cmp(result.reg(), 0);
   2170       result.Unuse();
   2171       dest->true_target()->Branch(cc);
   2172       dest->false_target()->Jump();
   2173 
   2174       is_smi.Bind();
   2175       left_side = Result(left_reg);
   2176       right_side = Result(right_val);
   2177       // Test smi equality and comparison by signed int comparison.
   2178       if (IsUnsafeSmi(right_side.handle())) {
   2179         right_side.ToRegister();
   2180         __ cmp(left_side.reg(), Operand(right_side.reg()));
   2181       } else {
   2182         __ cmp(Operand(left_side.reg()), Immediate(right_side.handle()));
   2183       }
   2184       left_side.Unuse();
   2185       right_side.Unuse();
   2186       dest->Split(cc);
   2187     }
   2188 
   2189   } else if (cc == equal &&
   2190              (left_side_constant_null || right_side_constant_null)) {
   2191     // To make null checks efficient, we check if either the left side or
   2192     // the right side is the constant 'null'.
   2193     // If so, we optimize the code by inlining a null check instead of
   2194     // calling the (very) general runtime routine for checking equality.
   2195     Result operand = left_side_constant_null ? right_side : left_side;
   2196     right_side.Unuse();
   2197     left_side.Unuse();
   2198     operand.ToRegister();
   2199     __ cmp(operand.reg(), Factory::null_value());
   2200     if (strict) {
   2201       operand.Unuse();
   2202       dest->Split(equal);
   2203     } else {
   2204       // The 'null' value is only equal to 'undefined' if using non-strict
   2205       // comparisons.
   2206       dest->true_target()->Branch(equal);
   2207       __ cmp(operand.reg(), Factory::undefined_value());
   2208       dest->true_target()->Branch(equal);
   2209       __ test(operand.reg(), Immediate(kSmiTagMask));
   2210       dest->false_target()->Branch(equal);
   2211 
   2212       // It can be an undetectable object.
   2213       // Use a scratch register in preference to spilling operand.reg().
   2214       Result temp = allocator()->Allocate();
   2215       ASSERT(temp.is_valid());
   2216       __ mov(temp.reg(),
   2217              FieldOperand(operand.reg(), HeapObject::kMapOffset));
   2218       __ movzx_b(temp.reg(),
   2219                  FieldOperand(temp.reg(), Map::kBitFieldOffset));
   2220       __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
   2221       temp.Unuse();
   2222       operand.Unuse();
   2223       dest->Split(not_zero);
   2224     }
   2225   } else if (left_side_constant_1_char_string ||
   2226              right_side_constant_1_char_string) {
   2227     if (left_side_constant_1_char_string && right_side_constant_1_char_string) {
   2228       // Trivial case, comparing two constants.
   2229       int left_value = String::cast(*left_side.handle())->Get(0);
   2230       int right_value = String::cast(*right_side.handle())->Get(0);
   2231       switch (cc) {
   2232         case less:
   2233           dest->Goto(left_value < right_value);
   2234           break;
   2235         case equal:
   2236           dest->Goto(left_value == right_value);
   2237           break;
   2238         case greater_equal:
   2239           dest->Goto(left_value >= right_value);
   2240           break;
   2241         default:
   2242           UNREACHABLE();
   2243       }
   2244     } else {
   2245       // Only one side is a constant 1 character string.
   2246       // If left side is a constant 1-character string, reverse the operands.
   2247       // Since one side is a constant string, conversion order does not matter.
   2248       if (left_side_constant_1_char_string) {
   2249         Result temp = left_side;
   2250         left_side = right_side;
   2251         right_side = temp;
   2252         cc = ReverseCondition(cc);
   2253         // This may reintroduce greater or less_equal as the value of cc.
   2254         // CompareStub and the inline code both support all values of cc.
   2255       }
   2256       // Implement comparison against a constant string, inlining the case
   2257       // where both sides are strings.
   2258       left_side.ToRegister();
   2259 
   2260       // Here we split control flow to the stub call and inlined cases
   2261       // before finally splitting it to the control destination.  We use
   2262       // a jump target and branching to duplicate the virtual frame at
   2263       // the first split.  We manually handle the off-frame references
   2264       // by reconstituting them on the non-fall-through path.
   2265       JumpTarget is_not_string, is_string;
   2266       Register left_reg = left_side.reg();
   2267       Handle<Object> right_val = right_side.handle();
   2268       __ test(left_side.reg(), Immediate(kSmiTagMask));
   2269       is_not_string.Branch(zero, &left_side);
   2270       Result temp = allocator_->Allocate();
   2271       ASSERT(temp.is_valid());
   2272       __ mov(temp.reg(),
   2273              FieldOperand(left_side.reg(), HeapObject::kMapOffset));
   2274       __ movzx_b(temp.reg(),
   2275                  FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
   2276       // If we are testing for equality then make use of the symbol shortcut.
   2277       // Check if the right left hand side has the same type as the left hand
   2278       // side (which is always a symbol).
   2279       if (cc == equal) {
   2280         Label not_a_symbol;
   2281         ASSERT(kSymbolTag != 0);
   2282         // Ensure that no non-strings have the symbol bit set.
   2283         ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
   2284         __ test(temp.reg(), Immediate(kIsSymbolMask));  // Test the symbol bit.
   2285         __ j(zero, &not_a_symbol);
   2286         // They are symbols, so do identity compare.
   2287         __ cmp(left_side.reg(), right_side.handle());
   2288         dest->true_target()->Branch(equal);
   2289         dest->false_target()->Branch(not_equal);
   2290         __ bind(&not_a_symbol);
   2291       }
   2292       // If the receiver is not a string of the type we handle call the stub.
   2293       __ and_(temp.reg(),
   2294           kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
   2295       __ cmp(temp.reg(), kStringTag | kSeqStringTag | kAsciiStringTag);
   2296       temp.Unuse();
   2297       is_string.Branch(equal, &left_side);
   2298 
   2299       // Setup and call the compare stub.
   2300       is_not_string.Bind(&left_side);
   2301       CompareStub stub(cc, strict, kCantBothBeNaN);
   2302       Result result = frame_->CallStub(&stub, &left_side, &right_side);
   2303       result.ToRegister();
   2304       __ cmp(result.reg(), 0);
   2305       result.Unuse();
   2306       dest->true_target()->Branch(cc);
   2307       dest->false_target()->Jump();
   2308 
   2309       is_string.Bind(&left_side);
   2310       // Here we know we have a sequential ASCII string.
   2311       left_side = Result(left_reg);
   2312       right_side = Result(right_val);
   2313       Result temp2 = allocator_->Allocate();
   2314       ASSERT(temp2.is_valid());
   2315       // Test string equality and comparison.
   2316       if (cc == equal) {
   2317         Label comparison_done;
   2318         __ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
   2319                Immediate(1));
   2320         __ j(not_equal, &comparison_done);
   2321         uint8_t char_value =
   2322             static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
   2323         __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
   2324                 char_value);
   2325         __ bind(&comparison_done);
   2326       } else {
   2327         __ mov(temp2.reg(),
   2328                FieldOperand(left_side.reg(), String::kLengthOffset));
   2329         __ sub(Operand(temp2.reg()), Immediate(1));
   2330         Label comparison;
   2331         // If the length is 0 then our subtraction gave -1 which compares less
   2332         // than any character.
   2333         __ j(negative, &comparison);
   2334         // Otherwise load the first character.
   2335         __ movzx_b(temp2.reg(),
   2336                    FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize));
   2337         __ bind(&comparison);
   2338         // Compare the first character of the string with out constant
   2339         // 1-character string.
   2340         uint8_t char_value =
   2341             static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
   2342         __ cmp(Operand(temp2.reg()), Immediate(char_value));
   2343         Label characters_were_different;
   2344         __ j(not_equal, &characters_were_different);
   2345         // If the first character is the same then the long string sorts after
   2346         // the short one.
   2347         __ cmp(FieldOperand(left_side.reg(), String::kLengthOffset),
   2348                Immediate(1));
   2349         __ bind(&characters_were_different);
   2350       }
   2351       temp2.Unuse();
   2352       left_side.Unuse();
   2353       right_side.Unuse();
   2354       dest->Split(cc);
   2355     }
   2356   } else {
   2357     // Neither side is a constant Smi or null.
   2358     // If either side is a non-smi constant, skip the smi check.
   2359     bool known_non_smi =
   2360         (left_side.is_constant() && !left_side.handle()->IsSmi()) ||
   2361         (right_side.is_constant() && !right_side.handle()->IsSmi());
   2362     NaNInformation nan_info =
   2363         (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ?
   2364         kBothCouldBeNaN :
   2365         kCantBothBeNaN;
   2366     left_side.ToRegister();
   2367     right_side.ToRegister();
   2368 
   2369     if (known_non_smi) {
   2370       // When non-smi, call out to the compare stub.
   2371       CompareStub stub(cc, strict, nan_info);
   2372       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
   2373       if (cc == equal) {
   2374         __ test(answer.reg(), Operand(answer.reg()));
   2375       } else {
   2376         __ cmp(answer.reg(), 0);
   2377       }
   2378       answer.Unuse();
   2379       dest->Split(cc);
   2380     } else {
   2381       // Here we split control flow to the stub call and inlined cases
   2382       // before finally splitting it to the control destination.  We use
   2383       // a jump target and branching to duplicate the virtual frame at
   2384       // the first split.  We manually handle the off-frame references
   2385       // by reconstituting them on the non-fall-through path.
   2386       JumpTarget is_smi;
   2387       Register left_reg = left_side.reg();
   2388       Register right_reg = right_side.reg();
   2389 
   2390       Result temp = allocator_->Allocate();
   2391       ASSERT(temp.is_valid());
   2392       __ mov(temp.reg(), left_side.reg());
   2393       __ or_(temp.reg(), Operand(right_side.reg()));
   2394       __ test(temp.reg(), Immediate(kSmiTagMask));
   2395       temp.Unuse();
   2396       is_smi.Branch(zero, taken);
   2397       // When non-smi, call out to the compare stub.
   2398       CompareStub stub(cc, strict, nan_info);
   2399       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
   2400       if (cc == equal) {
   2401         __ test(answer.reg(), Operand(answer.reg()));
   2402       } else {
   2403         __ cmp(answer.reg(), 0);
   2404       }
   2405       answer.Unuse();
   2406       dest->true_target()->Branch(cc);
   2407       dest->false_target()->Jump();
   2408 
   2409       is_smi.Bind();
   2410       left_side = Result(left_reg);
   2411       right_side = Result(right_reg);
   2412       __ cmp(left_side.reg(), Operand(right_side.reg()));
   2413       right_side.Unuse();
   2414       left_side.Unuse();
   2415       dest->Split(cc);
   2416     }
   2417   }
   2418 }
   2419 
   2420 
   2421 // Call the function just below TOS on the stack with the given
   2422 // arguments. The receiver is the TOS.
   2423 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
   2424                                       CallFunctionFlags flags,
   2425                                       int position) {
   2426   // Push the arguments ("left-to-right") on the stack.
   2427   int arg_count = args->length();
   2428   for (int i = 0; i < arg_count; i++) {
   2429     Load(args->at(i));
   2430   }
   2431 
   2432   // Record the position for debugging purposes.
   2433   CodeForSourcePosition(position);
   2434 
   2435   // Use the shared code stub to call the function.
   2436   InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   2437   CallFunctionStub call_function(arg_count, in_loop, flags);
   2438   Result answer = frame_->CallStub(&call_function, arg_count + 1);
   2439   // Restore context and replace function on the stack with the
   2440   // result of the stub invocation.
   2441   frame_->RestoreContextRegister();
   2442   frame_->SetElementAt(0, &answer);
   2443 }
   2444 
   2445 
   2446 void CodeGenerator::CallApplyLazy(Expression* applicand,
   2447                                   Expression* receiver,
   2448                                   VariableProxy* arguments,
   2449                                   int position) {
   2450   // An optimized implementation of expressions of the form
   2451   // x.apply(y, arguments).
   2452   // If the arguments object of the scope has not been allocated,
   2453   // and x.apply is Function.prototype.apply, this optimization
   2454   // just copies y and the arguments of the current function on the
   2455   // stack, as receiver and arguments, and calls x.
   2456   // In the implementation comments, we call x the applicand
   2457   // and y the receiver.
   2458   ASSERT(ArgumentsMode() == LAZY_ARGUMENTS_ALLOCATION);
   2459   ASSERT(arguments->IsArguments());
   2460 
   2461   // Load applicand.apply onto the stack. This will usually
   2462   // give us a megamorphic load site. Not super, but it works.
   2463   Load(applicand);
   2464   frame()->Dup();
   2465   Handle<String> name = Factory::LookupAsciiSymbol("apply");
   2466   frame()->Push(name);
   2467   Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET);
   2468   __ nop();
   2469   frame()->Push(&answer);
   2470 
   2471   // Load the receiver and the existing arguments object onto the
   2472   // expression stack. Avoid allocating the arguments object here.
   2473   Load(receiver);
   2474   Result existing_args =
   2475       LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
   2476   frame()->Push(&existing_args);
   2477 
   2478   // Emit the source position information after having loaded the
   2479   // receiver and the arguments.
   2480   CodeForSourcePosition(position);
   2481   // Contents of frame at this point:
   2482   // Frame[0]: arguments object of the current function or the hole.
   2483   // Frame[1]: receiver
   2484   // Frame[2]: applicand.apply
   2485   // Frame[3]: applicand.
   2486 
   2487   // Check if the arguments object has been lazily allocated
   2488   // already. If so, just use that instead of copying the arguments
   2489   // from the stack. This also deals with cases where a local variable
   2490   // named 'arguments' has been introduced.
   2491   frame_->Dup();
   2492   Result probe = frame_->Pop();
   2493   { VirtualFrame::SpilledScope spilled_scope;
   2494     Label slow, done;
   2495     bool try_lazy = true;
   2496     if (probe.is_constant()) {
   2497       try_lazy = probe.handle()->IsTheHole();
   2498     } else {
   2499       __ cmp(Operand(probe.reg()), Immediate(Factory::the_hole_value()));
   2500       probe.Unuse();
   2501       __ j(not_equal, &slow);
   2502     }
   2503 
   2504     if (try_lazy) {
   2505       Label build_args;
   2506       // Get rid of the arguments object probe.
   2507       frame_->Drop();  // Can be called on a spilled frame.
   2508       // Stack now has 3 elements on it.
   2509       // Contents of stack at this point:
   2510       // esp[0]: receiver
   2511       // esp[1]: applicand.apply
   2512       // esp[2]: applicand.
   2513 
   2514       // Check that the receiver really is a JavaScript object.
   2515       __ mov(eax, Operand(esp, 0));
   2516       __ test(eax, Immediate(kSmiTagMask));
   2517       __ j(zero, &build_args);
   2518       // We allow all JSObjects including JSFunctions.  As long as
   2519       // JS_FUNCTION_TYPE is the last instance type and it is right
   2520       // after LAST_JS_OBJECT_TYPE, we do not have to check the upper
   2521       // bound.
   2522       ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
   2523       ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
   2524       __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
   2525       __ j(below, &build_args);
   2526 
   2527       // Check that applicand.apply is Function.prototype.apply.
   2528       __ mov(eax, Operand(esp, kPointerSize));
   2529       __ test(eax, Immediate(kSmiTagMask));
   2530       __ j(zero, &build_args);
   2531       __ CmpObjectType(eax, JS_FUNCTION_TYPE, ecx);
   2532       __ j(not_equal, &build_args);
   2533       __ mov(ecx, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
   2534       Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply));
   2535       __ cmp(FieldOperand(ecx, SharedFunctionInfo::kCodeOffset),
   2536              Immediate(apply_code));
   2537       __ j(not_equal, &build_args);
   2538 
   2539       // Check that applicand is a function.
   2540       __ mov(edi, Operand(esp, 2 * kPointerSize));
   2541       __ test(edi, Immediate(kSmiTagMask));
   2542       __ j(zero, &build_args);
   2543       __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
   2544       __ j(not_equal, &build_args);
   2545 
   2546       // Copy the arguments to this function possibly from the
   2547       // adaptor frame below it.
   2548       Label invoke, adapted;
   2549       __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
   2550       __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
   2551       __ cmp(Operand(ecx),
   2552              Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   2553       __ j(equal, &adapted);
   2554 
   2555       // No arguments adaptor frame. Copy fixed number of arguments.
   2556       __ mov(eax, Immediate(scope()->num_parameters()));
   2557       for (int i = 0; i < scope()->num_parameters(); i++) {
   2558         __ push(frame_->ParameterAt(i));
   2559       }
   2560       __ jmp(&invoke);
   2561 
   2562       // Arguments adaptor frame present. Copy arguments from there, but
   2563       // avoid copying too many arguments to avoid stack overflows.
   2564       __ bind(&adapted);
   2565       static const uint32_t kArgumentsLimit = 1 * KB;
   2566       __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   2567       __ SmiUntag(eax);
   2568       __ mov(ecx, Operand(eax));
   2569       __ cmp(eax, kArgumentsLimit);
   2570       __ j(above, &build_args);
   2571 
   2572       // Loop through the arguments pushing them onto the execution
   2573       // stack. We don't inform the virtual frame of the push, so we don't
   2574       // have to worry about getting rid of the elements from the virtual
   2575       // frame.
   2576       Label loop;
   2577       // ecx is a small non-negative integer, due to the test above.
   2578       __ test(ecx, Operand(ecx));
   2579       __ j(zero, &invoke);
   2580       __ bind(&loop);
   2581       __ push(Operand(edx, ecx, times_pointer_size, 1 * kPointerSize));
   2582       __ dec(ecx);
   2583       __ j(not_zero, &loop);
   2584 
   2585       // Invoke the function.
   2586       __ bind(&invoke);
   2587       ParameterCount actual(eax);
   2588       __ InvokeFunction(edi, actual, CALL_FUNCTION);
   2589       // Drop applicand.apply and applicand from the stack, and push
   2590       // the result of the function call, but leave the spilled frame
   2591       // unchanged, with 3 elements, so it is correct when we compile the
   2592       // slow-case code.
   2593       __ add(Operand(esp), Immediate(2 * kPointerSize));
   2594       __ push(eax);
   2595       // Stack now has 1 element:
   2596       //   esp[0]: result
   2597       __ jmp(&done);
   2598 
   2599       // Slow-case: Allocate the arguments object since we know it isn't
   2600       // there, and fall-through to the slow-case where we call
   2601       // applicand.apply.
   2602       __ bind(&build_args);
   2603       // Stack now has 3 elements, because we have jumped from where:
   2604       // esp[0]: receiver
   2605       // esp[1]: applicand.apply
   2606       // esp[2]: applicand.
   2607 
   2608       // StoreArgumentsObject requires a correct frame, and may modify it.
   2609       Result arguments_object = StoreArgumentsObject(false);
   2610       frame_->SpillAll();
   2611       arguments_object.ToRegister();
   2612       frame_->EmitPush(arguments_object.reg());
   2613       arguments_object.Unuse();
   2614       // Stack and frame now have 4 elements.
   2615       __ bind(&slow);
   2616     }
   2617 
   2618     // Generic computation of x.apply(y, args) with no special optimization.
   2619     // Flip applicand.apply and applicand on the stack, so
   2620     // applicand looks like the receiver of the applicand.apply call.
   2621     // Then process it as a normal function call.
   2622     __ mov(eax, Operand(esp, 3 * kPointerSize));
   2623     __ mov(ebx, Operand(esp, 2 * kPointerSize));
   2624     __ mov(Operand(esp, 2 * kPointerSize), eax);
   2625     __ mov(Operand(esp, 3 * kPointerSize), ebx);
   2626 
   2627     CallFunctionStub call_function(2, NOT_IN_LOOP, NO_CALL_FUNCTION_FLAGS);
   2628     Result res = frame_->CallStub(&call_function, 3);
   2629     // The function and its two arguments have been dropped.
   2630     frame_->Drop(1);  // Drop the receiver as well.
   2631     res.ToRegister();
   2632     frame_->EmitPush(res.reg());
   2633     // Stack now has 1 element:
   2634     //   esp[0]: result
   2635     if (try_lazy) __ bind(&done);
   2636   }  // End of spilled scope.
   2637   // Restore the context register after a call.
   2638   frame_->RestoreContextRegister();
   2639 }
   2640 
   2641 
   2642 class DeferredStackCheck: public DeferredCode {
   2643  public:
   2644   DeferredStackCheck() {
   2645     set_comment("[ DeferredStackCheck");
   2646   }
   2647 
   2648   virtual void Generate();
   2649 };
   2650 
   2651 
   2652 void DeferredStackCheck::Generate() {
   2653   StackCheckStub stub;
   2654   __ CallStub(&stub);
   2655 }
   2656 
   2657 
   2658 void CodeGenerator::CheckStack() {
   2659   DeferredStackCheck* deferred = new DeferredStackCheck;
   2660   ExternalReference stack_limit =
   2661       ExternalReference::address_of_stack_limit();
   2662   __ cmp(esp, Operand::StaticVariable(stack_limit));
   2663   deferred->Branch(below);
   2664   deferred->BindExit();
   2665 }
   2666 
   2667 
   2668 void CodeGenerator::VisitAndSpill(Statement* statement) {
   2669   ASSERT(in_spilled_code());
   2670   set_in_spilled_code(false);
   2671   Visit(statement);
   2672   if (frame_ != NULL) {
   2673     frame_->SpillAll();
   2674   }
   2675   set_in_spilled_code(true);
   2676 }
   2677 
   2678 
   2679 void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) {
   2680   ASSERT(in_spilled_code());
   2681   set_in_spilled_code(false);
   2682   VisitStatements(statements);
   2683   if (frame_ != NULL) {
   2684     frame_->SpillAll();
   2685   }
   2686   set_in_spilled_code(true);
   2687 }
   2688 
   2689 
   2690 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
   2691   ASSERT(!in_spilled_code());
   2692   for (int i = 0; has_valid_frame() && i < statements->length(); i++) {
   2693     Visit(statements->at(i));
   2694   }
   2695 }
   2696 
   2697 
   2698 void CodeGenerator::VisitBlock(Block* node) {
   2699   ASSERT(!in_spilled_code());
   2700   Comment cmnt(masm_, "[ Block");
   2701   CodeForStatementPosition(node);
   2702   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   2703   VisitStatements(node->statements());
   2704   if (node->break_target()->is_linked()) {
   2705     node->break_target()->Bind();
   2706   }
   2707   node->break_target()->Unuse();
   2708 }
   2709 
   2710 
   2711 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   2712   // Call the runtime to declare the globals.  The inevitable call
   2713   // will sync frame elements to memory anyway, so we do it eagerly to
   2714   // allow us to push the arguments directly into place.
   2715   frame_->SyncRange(0, frame_->element_count() - 1);
   2716 
   2717   frame_->EmitPush(esi);  // The context is the first argument.
   2718   frame_->EmitPush(Immediate(pairs));
   2719   frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
   2720   Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
   2721   // Return value is ignored.
   2722 }
   2723 
   2724 
   2725 void CodeGenerator::VisitDeclaration(Declaration* node) {
   2726   Comment cmnt(masm_, "[ Declaration");
   2727   Variable* var = node->proxy()->var();
   2728   ASSERT(var != NULL);  // must have been resolved
   2729   Slot* slot = var->slot();
   2730 
   2731   // If it was not possible to allocate the variable at compile time,
   2732   // we need to "declare" it at runtime to make sure it actually
   2733   // exists in the local context.
   2734   if (slot != NULL && slot->type() == Slot::LOOKUP) {
   2735     // Variables with a "LOOKUP" slot were introduced as non-locals
   2736     // during variable resolution and must have mode DYNAMIC.
   2737     ASSERT(var->is_dynamic());
   2738     // For now, just do a runtime call.  Sync the virtual frame eagerly
   2739     // so we can simply push the arguments into place.
   2740     frame_->SyncRange(0, frame_->element_count() - 1);
   2741     frame_->EmitPush(esi);
   2742     frame_->EmitPush(Immediate(var->name()));
   2743     // Declaration nodes are always introduced in one of two modes.
   2744     ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST);
   2745     PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY;
   2746     frame_->EmitPush(Immediate(Smi::FromInt(attr)));
   2747     // Push initial value, if any.
   2748     // Note: For variables we must not push an initial value (such as
   2749     // 'undefined') because we may have a (legal) redeclaration and we
   2750     // must not destroy the current value.
   2751     if (node->mode() == Variable::CONST) {
   2752       frame_->EmitPush(Immediate(Factory::the_hole_value()));
   2753     } else if (node->fun() != NULL) {
   2754       Load(node->fun());
   2755     } else {
   2756       frame_->EmitPush(Immediate(Smi::FromInt(0)));  // no initial value!
   2757     }
   2758     Result ignored = frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
   2759     // Ignore the return value (declarations are statements).
   2760     return;
   2761   }
   2762 
   2763   ASSERT(!var->is_global());
   2764 
   2765   // If we have a function or a constant, we need to initialize the variable.
   2766   Expression* val = NULL;
   2767   if (node->mode() == Variable::CONST) {
   2768     val = new Literal(Factory::the_hole_value());
   2769   } else {
   2770     val = node->fun();  // NULL if we don't have a function
   2771   }
   2772 
   2773   if (val != NULL) {
   2774     {
   2775       // Set the initial value.
   2776       Reference target(this, node->proxy());
   2777       Load(val);
   2778       target.SetValue(NOT_CONST_INIT);
   2779       // The reference is removed from the stack (preserving TOS) when
   2780       // it goes out of scope.
   2781     }
   2782     // Get rid of the assigned value (declarations are statements).
   2783     frame_->Drop();
   2784   }
   2785 }
   2786 
   2787 
   2788 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
   2789   ASSERT(!in_spilled_code());
   2790   Comment cmnt(masm_, "[ ExpressionStatement");
   2791   CodeForStatementPosition(node);
   2792   Expression* expression = node->expression();
   2793   expression->MarkAsStatement();
   2794   Load(expression);
   2795   // Remove the lingering expression result from the top of stack.
   2796   frame_->Drop();
   2797 }
   2798 
   2799 
   2800 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
   2801   ASSERT(!in_spilled_code());
   2802   Comment cmnt(masm_, "// EmptyStatement");
   2803   CodeForStatementPosition(node);
   2804   // nothing to do
   2805 }
   2806 
   2807 
   2808 void CodeGenerator::VisitIfStatement(IfStatement* node) {
   2809   ASSERT(!in_spilled_code());
   2810   Comment cmnt(masm_, "[ IfStatement");
   2811   // Generate different code depending on which parts of the if statement
   2812   // are present or not.
   2813   bool has_then_stm = node->HasThenStatement();
   2814   bool has_else_stm = node->HasElseStatement();
   2815 
   2816   CodeForStatementPosition(node);
   2817   JumpTarget exit;
   2818   if (has_then_stm && has_else_stm) {
   2819     JumpTarget then;
   2820     JumpTarget else_;
   2821     ControlDestination dest(&then, &else_, true);
   2822     LoadCondition(node->condition(), &dest, true);
   2823 
   2824     if (dest.false_was_fall_through()) {
   2825       // The else target was bound, so we compile the else part first.
   2826       Visit(node->else_statement());
   2827 
   2828       // We may have dangling jumps to the then part.
   2829       if (then.is_linked()) {
   2830         if (has_valid_frame()) exit.Jump();
   2831         then.Bind();
   2832         Visit(node->then_statement());
   2833       }
   2834     } else {
   2835       // The then target was bound, so we compile the then part first.
   2836       Visit(node->then_statement());
   2837 
   2838       if (else_.is_linked()) {
   2839         if (has_valid_frame()) exit.Jump();
   2840         else_.Bind();
   2841         Visit(node->else_statement());
   2842       }
   2843     }
   2844 
   2845   } else if (has_then_stm) {
   2846     ASSERT(!has_else_stm);
   2847     JumpTarget then;
   2848     ControlDestination dest(&then, &exit, true);
   2849     LoadCondition(node->condition(), &dest, true);
   2850 
   2851     if (dest.false_was_fall_through()) {
   2852       // The exit label was bound.  We may have dangling jumps to the
   2853       // then part.
   2854       if (then.is_linked()) {
   2855         exit.Unuse();
   2856         exit.Jump();
   2857         then.Bind();
   2858         Visit(node->then_statement());
   2859       }
   2860     } else {
   2861       // The then label was bound.
   2862       Visit(node->then_statement());
   2863     }
   2864 
   2865   } else if (has_else_stm) {
   2866     ASSERT(!has_then_stm);
   2867     JumpTarget else_;
   2868     ControlDestination dest(&exit, &else_, false);
   2869     LoadCondition(node->condition(), &dest, true);
   2870 
   2871     if (dest.true_was_fall_through()) {
   2872       // The exit label was bound.  We may have dangling jumps to the
   2873       // else part.
   2874       if (else_.is_linked()) {
   2875         exit.Unuse();
   2876         exit.Jump();
   2877         else_.Bind();
   2878         Visit(node->else_statement());
   2879       }
   2880     } else {
   2881       // The else label was bound.
   2882       Visit(node->else_statement());
   2883     }
   2884 
   2885   } else {
   2886     ASSERT(!has_then_stm && !has_else_stm);
   2887     // We only care about the condition's side effects (not its value
   2888     // or control flow effect).  LoadCondition is called without
   2889     // forcing control flow.
   2890     ControlDestination dest(&exit, &exit, true);
   2891     LoadCondition(node->condition(), &dest, false);
   2892     if (!dest.is_used()) {
   2893       // We got a value on the frame rather than (or in addition to)
   2894       // control flow.
   2895       frame_->Drop();
   2896     }
   2897   }
   2898 
   2899   if (exit.is_linked()) {
   2900     exit.Bind();
   2901   }
   2902 }
   2903 
   2904 
   2905 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
   2906   ASSERT(!in_spilled_code());
   2907   Comment cmnt(masm_, "[ ContinueStatement");
   2908   CodeForStatementPosition(node);
   2909   node->target()->continue_target()->Jump();
   2910 }
   2911 
   2912 
   2913 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
   2914   ASSERT(!in_spilled_code());
   2915   Comment cmnt(masm_, "[ BreakStatement");
   2916   CodeForStatementPosition(node);
   2917   node->target()->break_target()->Jump();
   2918 }
   2919 
   2920 
   2921 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
   2922   ASSERT(!in_spilled_code());
   2923   Comment cmnt(masm_, "[ ReturnStatement");
   2924 
   2925   CodeForStatementPosition(node);
   2926   Load(node->expression());
   2927   Result return_value = frame_->Pop();
   2928   masm()->WriteRecordedPositions();
   2929   if (function_return_is_shadowed_) {
   2930     function_return_.Jump(&return_value);
   2931   } else {
   2932     frame_->PrepareForReturn();
   2933     if (function_return_.is_bound()) {
   2934       // If the function return label is already bound we reuse the
   2935       // code by jumping to the return site.
   2936       function_return_.Jump(&return_value);
   2937     } else {
   2938       function_return_.Bind(&return_value);
   2939       GenerateReturnSequence(&return_value);
   2940     }
   2941   }
   2942 }
   2943 
   2944 
   2945 void CodeGenerator::GenerateReturnSequence(Result* return_value) {
   2946   // The return value is a live (but not currently reference counted)
   2947   // reference to eax.  This is safe because the current frame does not
   2948   // contain a reference to eax (it is prepared for the return by spilling
   2949   // all registers).
   2950   if (FLAG_trace) {
   2951     frame_->Push(return_value);
   2952     *return_value = frame_->CallRuntime(Runtime::kTraceExit, 1);
   2953   }
   2954   return_value->ToRegister(eax);
   2955 
   2956   // Add a label for checking the size of the code used for returning.
   2957   Label check_exit_codesize;
   2958   masm_->bind(&check_exit_codesize);
   2959 
   2960   // Leave the frame and return popping the arguments and the
   2961   // receiver.
   2962   frame_->Exit();
   2963   masm_->ret((scope()->num_parameters() + 1) * kPointerSize);
   2964   DeleteFrame();
   2965 
   2966 #ifdef ENABLE_DEBUGGER_SUPPORT
   2967   // Check that the size of the code used for returning matches what is
   2968   // expected by the debugger.
   2969   ASSERT_EQ(Assembler::kJSReturnSequenceLength,
   2970             masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
   2971 #endif
   2972 }
   2973 
   2974 
   2975 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
   2976   ASSERT(!in_spilled_code());
   2977   Comment cmnt(masm_, "[ WithEnterStatement");
   2978   CodeForStatementPosition(node);
   2979   Load(node->expression());
   2980   Result context;
   2981   if (node->is_catch_block()) {
   2982     context = frame_->CallRuntime(Runtime::kPushCatchContext, 1);
   2983   } else {
   2984     context = frame_->CallRuntime(Runtime::kPushContext, 1);
   2985   }
   2986 
   2987   // Update context local.
   2988   frame_->SaveContextRegister();
   2989 
   2990   // Verify that the runtime call result and esi agree.
   2991   if (FLAG_debug_code) {
   2992     __ cmp(context.reg(), Operand(esi));
   2993     __ Assert(equal, "Runtime::NewContext should end up in esi");
   2994   }
   2995 }
   2996 
   2997 
   2998 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
   2999   ASSERT(!in_spilled_code());
   3000   Comment cmnt(masm_, "[ WithExitStatement");
   3001   CodeForStatementPosition(node);
   3002   // Pop context.
   3003   __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX));
   3004   // Update context local.
   3005   frame_->SaveContextRegister();
   3006 }
   3007 
   3008 
   3009 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
   3010   ASSERT(!in_spilled_code());
   3011   Comment cmnt(masm_, "[ SwitchStatement");
   3012   CodeForStatementPosition(node);
   3013   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3014 
   3015   // Compile the switch value.
   3016   Load(node->tag());
   3017 
   3018   ZoneList<CaseClause*>* cases = node->cases();
   3019   int length = cases->length();
   3020   CaseClause* default_clause = NULL;
   3021 
   3022   JumpTarget next_test;
   3023   // Compile the case label expressions and comparisons.  Exit early
   3024   // if a comparison is unconditionally true.  The target next_test is
   3025   // bound before the loop in order to indicate control flow to the
   3026   // first comparison.
   3027   next_test.Bind();
   3028   for (int i = 0; i < length && !next_test.is_unused(); i++) {
   3029     CaseClause* clause = cases->at(i);
   3030     // The default is not a test, but remember it for later.
   3031     if (clause->is_default()) {
   3032       default_clause = clause;
   3033       continue;
   3034     }
   3035 
   3036     Comment cmnt(masm_, "[ Case comparison");
   3037     // We recycle the same target next_test for each test.  Bind it if
   3038     // the previous test has not done so and then unuse it for the
   3039     // loop.
   3040     if (next_test.is_linked()) {
   3041       next_test.Bind();
   3042     }
   3043     next_test.Unuse();
   3044 
   3045     // Duplicate the switch value.
   3046     frame_->Dup();
   3047 
   3048     // Compile the label expression.
   3049     Load(clause->label());
   3050 
   3051     // Compare and branch to the body if true or the next test if
   3052     // false.  Prefer the next test as a fall through.
   3053     ControlDestination dest(clause->body_target(), &next_test, false);
   3054     Comparison(node, equal, true, &dest);
   3055 
   3056     // If the comparison fell through to the true target, jump to the
   3057     // actual body.
   3058     if (dest.true_was_fall_through()) {
   3059       clause->body_target()->Unuse();
   3060       clause->body_target()->Jump();
   3061     }
   3062   }
   3063 
   3064   // If there was control flow to a next test from the last one
   3065   // compiled, compile a jump to the default or break target.
   3066   if (!next_test.is_unused()) {
   3067     if (next_test.is_linked()) {
   3068       next_test.Bind();
   3069     }
   3070     // Drop the switch value.
   3071     frame_->Drop();
   3072     if (default_clause != NULL) {
   3073       default_clause->body_target()->Jump();
   3074     } else {
   3075       node->break_target()->Jump();
   3076     }
   3077   }
   3078 
   3079 
   3080   // The last instruction emitted was a jump, either to the default
   3081   // clause or the break target, or else to a case body from the loop
   3082   // that compiles the tests.
   3083   ASSERT(!has_valid_frame());
   3084   // Compile case bodies as needed.
   3085   for (int i = 0; i < length; i++) {
   3086     CaseClause* clause = cases->at(i);
   3087 
   3088     // There are two ways to reach the body: from the corresponding
   3089     // test or as the fall through of the previous body.
   3090     if (clause->body_target()->is_linked() || has_valid_frame()) {
   3091       if (clause->body_target()->is_linked()) {
   3092         if (has_valid_frame()) {
   3093           // If we have both a jump to the test and a fall through, put
   3094           // a jump on the fall through path to avoid the dropping of
   3095           // the switch value on the test path.  The exception is the
   3096           // default which has already had the switch value dropped.
   3097           if (clause->is_default()) {
   3098             clause->body_target()->Bind();
   3099           } else {
   3100             JumpTarget body;
   3101             body.Jump();
   3102             clause->body_target()->Bind();
   3103             frame_->Drop();
   3104             body.Bind();
   3105           }
   3106         } else {
   3107           // No fall through to worry about.
   3108           clause->body_target()->Bind();
   3109           if (!clause->is_default()) {
   3110             frame_->Drop();
   3111           }
   3112         }
   3113       } else {
   3114         // Otherwise, we have only fall through.
   3115         ASSERT(has_valid_frame());
   3116       }
   3117 
   3118       // We are now prepared to compile the body.
   3119       Comment cmnt(masm_, "[ Case body");
   3120       VisitStatements(clause->statements());
   3121     }
   3122     clause->body_target()->Unuse();
   3123   }
   3124 
   3125   // We may not have a valid frame here so bind the break target only
   3126   // if needed.
   3127   if (node->break_target()->is_linked()) {
   3128     node->break_target()->Bind();
   3129   }
   3130   node->break_target()->Unuse();
   3131 }
   3132 
   3133 
   3134 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
   3135   ASSERT(!in_spilled_code());
   3136   Comment cmnt(masm_, "[ DoWhileStatement");
   3137   CodeForStatementPosition(node);
   3138   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3139   JumpTarget body(JumpTarget::BIDIRECTIONAL);
   3140   IncrementLoopNesting();
   3141 
   3142   ConditionAnalysis info = AnalyzeCondition(node->cond());
   3143   // Label the top of the loop for the backward jump if necessary.
   3144   switch (info) {
   3145     case ALWAYS_TRUE:
   3146       // Use the continue target.
   3147       node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   3148       node->continue_target()->Bind();
   3149       break;
   3150     case ALWAYS_FALSE:
   3151       // No need to label it.
   3152       node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3153       break;
   3154     case DONT_KNOW:
   3155       // Continue is the test, so use the backward body target.
   3156       node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3157       body.Bind();
   3158       break;
   3159   }
   3160 
   3161   CheckStack();  // TODO(1222600): ignore if body contains calls.
   3162   Visit(node->body());
   3163 
   3164   // Compile the test.
   3165   switch (info) {
   3166     case ALWAYS_TRUE:
   3167       // If control flow can fall off the end of the body, jump back to
   3168       // the top and bind the break target at the exit.
   3169       if (has_valid_frame()) {
   3170         node->continue_target()->Jump();
   3171       }
   3172       if (node->break_target()->is_linked()) {
   3173         node->break_target()->Bind();
   3174       }
   3175       break;
   3176     case ALWAYS_FALSE:
   3177       // We may have had continues or breaks in the body.
   3178       if (node->continue_target()->is_linked()) {
   3179         node->continue_target()->Bind();
   3180       }
   3181       if (node->break_target()->is_linked()) {
   3182         node->break_target()->Bind();
   3183       }
   3184       break;
   3185     case DONT_KNOW:
   3186       // We have to compile the test expression if it can be reached by
   3187       // control flow falling out of the body or via continue.
   3188       if (node->continue_target()->is_linked()) {
   3189         node->continue_target()->Bind();
   3190       }
   3191       if (has_valid_frame()) {
   3192         Comment cmnt(masm_, "[ DoWhileCondition");
   3193         CodeForDoWhileConditionPosition(node);
   3194         ControlDestination dest(&body, node->break_target(), false);
   3195         LoadCondition(node->cond(), &dest, true);
   3196       }
   3197       if (node->break_target()->is_linked()) {
   3198         node->break_target()->Bind();
   3199       }
   3200       break;
   3201   }
   3202 
   3203   DecrementLoopNesting();
   3204 }
   3205 
   3206 
   3207 void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
   3208   ASSERT(!in_spilled_code());
   3209   Comment cmnt(masm_, "[ WhileStatement");
   3210   CodeForStatementPosition(node);
   3211 
   3212   // If the condition is always false and has no side effects, we do not
   3213   // need to compile anything.
   3214   ConditionAnalysis info = AnalyzeCondition(node->cond());
   3215   if (info == ALWAYS_FALSE) return;
   3216 
   3217   // Do not duplicate conditions that may have function literal
   3218   // subexpressions.  This can cause us to compile the function literal
   3219   // twice.
   3220   bool test_at_bottom = !node->may_have_function_literal();
   3221   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3222   IncrementLoopNesting();
   3223   JumpTarget body;
   3224   if (test_at_bottom) {
   3225     body.set_direction(JumpTarget::BIDIRECTIONAL);
   3226   }
   3227 
   3228   // Based on the condition analysis, compile the test as necessary.
   3229   switch (info) {
   3230     case ALWAYS_TRUE:
   3231       // We will not compile the test expression.  Label the top of the
   3232       // loop with the continue target.
   3233       node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   3234       node->continue_target()->Bind();
   3235       break;
   3236     case DONT_KNOW: {
   3237       if (test_at_bottom) {
   3238         // Continue is the test at the bottom, no need to label the test
   3239         // at the top.  The body is a backward target.
   3240         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3241       } else {
   3242         // Label the test at the top as the continue target.  The body
   3243         // is a forward-only target.
   3244         node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   3245         node->continue_target()->Bind();
   3246       }
   3247       // Compile the test with the body as the true target and preferred
   3248       // fall-through and with the break target as the false target.
   3249       ControlDestination dest(&body, node->break_target(), true);
   3250       LoadCondition(node->cond(), &dest, true);
   3251 
   3252       if (dest.false_was_fall_through()) {
   3253         // If we got the break target as fall-through, the test may have
   3254         // been unconditionally false (if there are no jumps to the
   3255         // body).
   3256         if (!body.is_linked()) {
   3257           DecrementLoopNesting();
   3258           return;
   3259         }
   3260 
   3261         // Otherwise, jump around the body on the fall through and then
   3262         // bind the body target.
   3263         node->break_target()->Unuse();
   3264         node->break_target()->Jump();
   3265         body.Bind();
   3266       }
   3267       break;
   3268     }
   3269     case ALWAYS_FALSE:
   3270       UNREACHABLE();
   3271       break;
   3272   }
   3273 
   3274   CheckStack();  // TODO(1222600): ignore if body contains calls.
   3275   Visit(node->body());
   3276 
   3277   // Based on the condition analysis, compile the backward jump as
   3278   // necessary.
   3279   switch (info) {
   3280     case ALWAYS_TRUE:
   3281       // The loop body has been labeled with the continue target.
   3282       if (has_valid_frame()) {
   3283         node->continue_target()->Jump();
   3284       }
   3285       break;
   3286     case DONT_KNOW:
   3287       if (test_at_bottom) {
   3288         // If we have chosen to recompile the test at the bottom, then
   3289         // it is the continue target.
   3290         if (node->continue_target()->is_linked()) {
   3291           node->continue_target()->Bind();
   3292         }
   3293         if (has_valid_frame()) {
   3294           // The break target is the fall-through (body is a backward
   3295           // jump from here and thus an invalid fall-through).
   3296           ControlDestination dest(&body, node->break_target(), false);
   3297           LoadCondition(node->cond(), &dest, true);
   3298         }
   3299       } else {
   3300         // If we have chosen not to recompile the test at the bottom,
   3301         // jump back to the one at the top.
   3302         if (has_valid_frame()) {
   3303           node->continue_target()->Jump();
   3304         }
   3305       }
   3306       break;
   3307     case ALWAYS_FALSE:
   3308       UNREACHABLE();
   3309       break;
   3310   }
   3311 
   3312   // The break target may be already bound (by the condition), or there
   3313   // may not be a valid frame.  Bind it only if needed.
   3314   if (node->break_target()->is_linked()) {
   3315     node->break_target()->Bind();
   3316   }
   3317   DecrementLoopNesting();
   3318 }
   3319 
   3320 
   3321 void CodeGenerator::VisitForStatement(ForStatement* node) {
   3322   ASSERT(!in_spilled_code());
   3323   Comment cmnt(masm_, "[ ForStatement");
   3324   CodeForStatementPosition(node);
   3325 
   3326   // Compile the init expression if present.
   3327   if (node->init() != NULL) {
   3328     Visit(node->init());
   3329   }
   3330 
   3331   // If the condition is always false and has no side effects, we do not
   3332   // need to compile anything else.
   3333   ConditionAnalysis info = AnalyzeCondition(node->cond());
   3334   if (info == ALWAYS_FALSE) return;
   3335 
   3336   // Do not duplicate conditions that may have function literal
   3337   // subexpressions.  This can cause us to compile the function literal
   3338   // twice.
   3339   bool test_at_bottom = !node->may_have_function_literal();
   3340   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3341   IncrementLoopNesting();
   3342 
   3343   // Target for backward edge if no test at the bottom, otherwise
   3344   // unused.
   3345   JumpTarget loop(JumpTarget::BIDIRECTIONAL);
   3346 
   3347   // Target for backward edge if there is a test at the bottom,
   3348   // otherwise used as target for test at the top.
   3349   JumpTarget body;
   3350   if (test_at_bottom) {
   3351     body.set_direction(JumpTarget::BIDIRECTIONAL);
   3352   }
   3353 
   3354   // Based on the condition analysis, compile the test as necessary.
   3355   switch (info) {
   3356     case ALWAYS_TRUE:
   3357       // We will not compile the test expression.  Label the top of the
   3358       // loop.
   3359       if (node->next() == NULL) {
   3360         // Use the continue target if there is no update expression.
   3361         node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   3362         node->continue_target()->Bind();
   3363       } else {
   3364         // Otherwise use the backward loop target.
   3365         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3366         loop.Bind();
   3367       }
   3368       break;
   3369     case DONT_KNOW: {
   3370       if (test_at_bottom) {
   3371         // Continue is either the update expression or the test at the
   3372         // bottom, no need to label the test at the top.
   3373         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3374       } else if (node->next() == NULL) {
   3375         // We are not recompiling the test at the bottom and there is no
   3376         // update expression.
   3377         node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
   3378         node->continue_target()->Bind();
   3379       } else {
   3380         // We are not recompiling the test at the bottom and there is an
   3381         // update expression.
   3382         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3383         loop.Bind();
   3384       }
   3385       // Compile the test with the body as the true target and preferred
   3386       // fall-through and with the break target as the false target.
   3387       ControlDestination dest(&body, node->break_target(), true);
   3388       LoadCondition(node->cond(), &dest, true);
   3389 
   3390       if (dest.false_was_fall_through()) {
   3391         // If we got the break target as fall-through, the test may have
   3392         // been unconditionally false (if there are no jumps to the
   3393         // body).
   3394         if (!body.is_linked()) {
   3395           DecrementLoopNesting();
   3396           return;
   3397         }
   3398 
   3399         // Otherwise, jump around the body on the fall through and then
   3400         // bind the body target.
   3401         node->break_target()->Unuse();
   3402         node->break_target()->Jump();
   3403         body.Bind();
   3404       }
   3405       break;
   3406     }
   3407     case ALWAYS_FALSE:
   3408       UNREACHABLE();
   3409       break;
   3410   }
   3411 
   3412   CheckStack();  // TODO(1222600): ignore if body contains calls.
   3413   Visit(node->body());
   3414 
   3415   // If there is an update expression, compile it if necessary.
   3416   if (node->next() != NULL) {
   3417     if (node->continue_target()->is_linked()) {
   3418       node->continue_target()->Bind();
   3419     }
   3420 
   3421     // Control can reach the update by falling out of the body or by a
   3422     // continue.
   3423     if (has_valid_frame()) {
   3424       // Record the source position of the statement as this code which
   3425       // is after the code for the body actually belongs to the loop
   3426       // statement and not the body.
   3427       CodeForStatementPosition(node);
   3428       Visit(node->next());
   3429     }
   3430   }
   3431 
   3432   // Based on the condition analysis, compile the backward jump as
   3433   // necessary.
   3434   switch (info) {
   3435     case ALWAYS_TRUE:
   3436       if (has_valid_frame()) {
   3437         if (node->next() == NULL) {
   3438           node->continue_target()->Jump();
   3439         } else {
   3440           loop.Jump();
   3441         }
   3442       }
   3443       break;
   3444     case DONT_KNOW:
   3445       if (test_at_bottom) {
   3446         if (node->continue_target()->is_linked()) {
   3447           // We can have dangling jumps to the continue target if there
   3448           // was no update expression.
   3449           node->continue_target()->Bind();
   3450         }
   3451         // Control can reach the test at the bottom by falling out of
   3452         // the body, by a continue in the body, or from the update
   3453         // expression.
   3454         if (has_valid_frame()) {
   3455           // The break target is the fall-through (body is a backward
   3456           // jump from here).
   3457           ControlDestination dest(&body, node->break_target(), false);
   3458           LoadCondition(node->cond(), &dest, true);
   3459         }
   3460       } else {
   3461         // Otherwise, jump back to the test at the top.
   3462         if (has_valid_frame()) {
   3463           if (node->next() == NULL) {
   3464             node->continue_target()->Jump();
   3465           } else {
   3466             loop.Jump();
   3467           }
   3468         }
   3469       }
   3470       break;
   3471     case ALWAYS_FALSE:
   3472       UNREACHABLE();
   3473       break;
   3474   }
   3475 
   3476   // The break target may be already bound (by the condition), or
   3477   // there may not be a valid frame.  Bind it only if needed.
   3478   if (node->break_target()->is_linked()) {
   3479     node->break_target()->Bind();
   3480   }
   3481   DecrementLoopNesting();
   3482 }
   3483 
   3484 
   3485 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
   3486   ASSERT(!in_spilled_code());
   3487   VirtualFrame::SpilledScope spilled_scope;
   3488   Comment cmnt(masm_, "[ ForInStatement");
   3489   CodeForStatementPosition(node);
   3490 
   3491   JumpTarget primitive;
   3492   JumpTarget jsobject;
   3493   JumpTarget fixed_array;
   3494   JumpTarget entry(JumpTarget::BIDIRECTIONAL);
   3495   JumpTarget end_del_check;
   3496   JumpTarget exit;
   3497 
   3498   // Get the object to enumerate over (converted to JSObject).
   3499   LoadAndSpill(node->enumerable());
   3500 
   3501   // Both SpiderMonkey and kjs ignore null and undefined in contrast
   3502   // to the specification.  12.6.4 mandates a call to ToObject.
   3503   frame_->EmitPop(eax);
   3504 
   3505   // eax: value to be iterated over
   3506   __ cmp(eax, Factory::undefined_value());
   3507   exit.Branch(equal);
   3508   __ cmp(eax, Factory::null_value());
   3509   exit.Branch(equal);
   3510 
   3511   // Stack layout in body:
   3512   // [iteration counter (smi)] <- slot 0
   3513   // [length of array]         <- slot 1
   3514   // [FixedArray]              <- slot 2
   3515   // [Map or 0]                <- slot 3
   3516   // [Object]                  <- slot 4
   3517 
   3518   // Check if enumerable is already a JSObject
   3519   // eax: value to be iterated over
   3520   __ test(eax, Immediate(kSmiTagMask));
   3521   primitive.Branch(zero);
   3522   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
   3523   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   3524   __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
   3525   jsobject.Branch(above_equal);
   3526 
   3527   primitive.Bind();
   3528   frame_->EmitPush(eax);
   3529   frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION, 1);
   3530   // function call returns the value in eax, which is where we want it below
   3531 
   3532   jsobject.Bind();
   3533   // Get the set of properties (as a FixedArray or Map).
   3534   // eax: value to be iterated over
   3535   frame_->EmitPush(eax);  // Push the object being iterated over.
   3536 
   3537   // Check cache validity in generated code. This is a fast case for
   3538   // the JSObject::IsSimpleEnum cache validity checks. If we cannot
   3539   // guarantee cache validity, call the runtime system to check cache
   3540   // validity or get the property names in a fixed array.
   3541   JumpTarget call_runtime;
   3542   JumpTarget loop(JumpTarget::BIDIRECTIONAL);
   3543   JumpTarget check_prototype;
   3544   JumpTarget use_cache;
   3545   __ mov(ecx, eax);
   3546   loop.Bind();
   3547   // Check that there are no elements.
   3548   __ mov(edx, FieldOperand(ecx, JSObject::kElementsOffset));
   3549   __ cmp(Operand(edx), Immediate(Factory::empty_fixed_array()));
   3550   call_runtime.Branch(not_equal);
   3551   // Check that instance descriptors are not empty so that we can
   3552   // check for an enum cache.  Leave the map in ebx for the subsequent
   3553   // prototype load.
   3554   __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
   3555   __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
   3556   __ cmp(Operand(edx), Immediate(Factory::empty_descriptor_array()));
   3557   call_runtime.Branch(equal);
   3558   // Check that there in an enum cache in the non-empty instance
   3559   // descriptors.  This is the case if the next enumeration index
   3560   // field does not contain a smi.
   3561   __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
   3562   __ test(edx, Immediate(kSmiTagMask));
   3563   call_runtime.Branch(zero);
   3564   // For all objects but the receiver, check that the cache is empty.
   3565   __ cmp(ecx, Operand(eax));
   3566   check_prototype.Branch(equal);
   3567   __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
   3568   __ cmp(Operand(edx), Immediate(Factory::empty_fixed_array()));
   3569   call_runtime.Branch(not_equal);
   3570   check_prototype.Bind();
   3571   // Load the prototype from the map and loop if non-null.
   3572   __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
   3573   __ cmp(Operand(ecx), Immediate(Factory::null_value()));
   3574   loop.Branch(not_equal);
   3575   // The enum cache is valid.  Load the map of the object being
   3576   // iterated over and use the cache for the iteration.
   3577   __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
   3578   use_cache.Jump();
   3579 
   3580   call_runtime.Bind();
   3581   // Call the runtime to get the property names for the object.
   3582   frame_->EmitPush(eax);  // push the Object (slot 4) for the runtime call
   3583   frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1);
   3584 
   3585   // If we got a map from the runtime call, we can do a fast
   3586   // modification check. Otherwise, we got a fixed array, and we have
   3587   // to do a slow check.
   3588   // eax: map or fixed array (result from call to
   3589   // Runtime::kGetPropertyNamesFast)
   3590   __ mov(edx, Operand(eax));
   3591   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   3592   __ cmp(ecx, Factory::meta_map());
   3593   fixed_array.Branch(not_equal);
   3594 
   3595   use_cache.Bind();
   3596   // Get enum cache
   3597   // eax: map (either the result from a call to
   3598   // Runtime::kGetPropertyNamesFast or has been fetched directly from
   3599   // the object)
   3600   __ mov(ecx, Operand(eax));
   3601 
   3602   __ mov(ecx, FieldOperand(ecx, Map::kInstanceDescriptorsOffset));
   3603   // Get the bridge array held in the enumeration index field.
   3604   __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumerationIndexOffset));
   3605   // Get the cache from the bridge array.
   3606   __ mov(edx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset));
   3607 
   3608   frame_->EmitPush(eax);  // <- slot 3
   3609   frame_->EmitPush(edx);  // <- slot 2
   3610   __ mov(eax, FieldOperand(edx, FixedArray::kLengthOffset));
   3611   __ SmiTag(eax);
   3612   frame_->EmitPush(eax);  // <- slot 1
   3613   frame_->EmitPush(Immediate(Smi::FromInt(0)));  // <- slot 0
   3614   entry.Jump();
   3615 
   3616   fixed_array.Bind();
   3617   // eax: fixed array (result from call to Runtime::kGetPropertyNamesFast)
   3618   frame_->EmitPush(Immediate(Smi::FromInt(0)));  // <- slot 3
   3619   frame_->EmitPush(eax);  // <- slot 2
   3620 
   3621   // Push the length of the array and the initial index onto the stack.
   3622   __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset));
   3623   __ SmiTag(eax);
   3624   frame_->EmitPush(eax);  // <- slot 1
   3625   frame_->EmitPush(Immediate(Smi::FromInt(0)));  // <- slot 0
   3626 
   3627   // Condition.
   3628   entry.Bind();
   3629   // Grab the current frame's height for the break and continue
   3630   // targets only after all the state is pushed on the frame.
   3631   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3632   node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
   3633 
   3634   __ mov(eax, frame_->ElementAt(0));  // load the current count
   3635   __ cmp(eax, frame_->ElementAt(1));  // compare to the array length
   3636   node->break_target()->Branch(above_equal);
   3637 
   3638   // Get the i'th entry of the array.
   3639   __ mov(edx, frame_->ElementAt(2));
   3640   __ mov(ebx, Operand(edx, eax, times_2,
   3641                       FixedArray::kHeaderSize - kHeapObjectTag));
   3642 
   3643   // Get the expected map from the stack or a zero map in the
   3644   // permanent slow case eax: current iteration count ebx: i'th entry
   3645   // of the enum cache
   3646   __ mov(edx, frame_->ElementAt(3));
   3647   // Check if the expected map still matches that of the enumerable.
   3648   // If not, we have to filter the key.
   3649   // eax: current iteration count
   3650   // ebx: i'th entry of the enum cache
   3651   // edx: expected map value
   3652   __ mov(ecx, frame_->ElementAt(4));
   3653   __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
   3654   __ cmp(ecx, Operand(edx));
   3655   end_del_check.Branch(equal);
   3656 
   3657   // Convert the entry to a string (or null if it isn't a property anymore).
   3658   frame_->EmitPush(frame_->ElementAt(4));  // push enumerable
   3659   frame_->EmitPush(ebx);  // push entry
   3660   frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION, 2);
   3661   __ mov(ebx, Operand(eax));
   3662 
   3663   // If the property has been removed while iterating, we just skip it.
   3664   __ cmp(ebx, Factory::null_value());
   3665   node->continue_target()->Branch(equal);
   3666 
   3667   end_del_check.Bind();
   3668   // Store the entry in the 'each' expression and take another spin in the
   3669   // loop.  edx: i'th entry of the enum cache (or string there of)
   3670   frame_->EmitPush(ebx);
   3671   { Reference each(this, node->each());
   3672     // Loading a reference may leave the frame in an unspilled state.
   3673     frame_->SpillAll();
   3674     if (!each.is_illegal()) {
   3675       if (each.size() > 0) {
   3676         frame_->EmitPush(frame_->ElementAt(each.size()));
   3677         each.SetValue(NOT_CONST_INIT);
   3678         frame_->Drop(2);
   3679       } else {
   3680         // If the reference was to a slot we rely on the convenient property
   3681         // that it doesn't matter whether a value (eg, ebx pushed above) is
   3682         // right on top of or right underneath a zero-sized reference.
   3683         each.SetValue(NOT_CONST_INIT);
   3684         frame_->Drop();
   3685       }
   3686     }
   3687   }
   3688   // Unloading a reference may leave the frame in an unspilled state.
   3689   frame_->SpillAll();
   3690 
   3691   // Body.
   3692   CheckStack();  // TODO(1222600): ignore if body contains calls.
   3693   VisitAndSpill(node->body());
   3694 
   3695   // Next.  Reestablish a spilled frame in case we are coming here via
   3696   // a continue in the body.
   3697   node->continue_target()->Bind();
   3698   frame_->SpillAll();
   3699   frame_->EmitPop(eax);
   3700   __ add(Operand(eax), Immediate(Smi::FromInt(1)));
   3701   frame_->EmitPush(eax);
   3702   entry.Jump();
   3703 
   3704   // Cleanup.  No need to spill because VirtualFrame::Drop is safe for
   3705   // any frame.
   3706   node->break_target()->Bind();
   3707   frame_->Drop(5);
   3708 
   3709   // Exit.
   3710   exit.Bind();
   3711 
   3712   node->continue_target()->Unuse();
   3713   node->break_target()->Unuse();
   3714 }
   3715 
   3716 
   3717 void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
   3718   ASSERT(!in_spilled_code());
   3719   VirtualFrame::SpilledScope spilled_scope;
   3720   Comment cmnt(masm_, "[ TryCatchStatement");
   3721   CodeForStatementPosition(node);
   3722 
   3723   JumpTarget try_block;
   3724   JumpTarget exit;
   3725 
   3726   try_block.Call();
   3727   // --- Catch block ---
   3728   frame_->EmitPush(eax);
   3729 
   3730   // Store the caught exception in the catch variable.
   3731   Variable* catch_var = node->catch_var()->var();
   3732   ASSERT(catch_var != NULL && catch_var->slot() != NULL);
   3733   StoreToSlot(catch_var->slot(), NOT_CONST_INIT);
   3734 
   3735   // Remove the exception from the stack.
   3736   frame_->Drop();
   3737 
   3738   VisitStatementsAndSpill(node->catch_block()->statements());
   3739   if (has_valid_frame()) {
   3740     exit.Jump();
   3741   }
   3742 
   3743 
   3744   // --- Try block ---
   3745   try_block.Bind();
   3746 
   3747   frame_->PushTryHandler(TRY_CATCH_HANDLER);
   3748   int handler_height = frame_->height();
   3749 
   3750   // Shadow the jump targets for all escapes from the try block, including
   3751   // returns.  During shadowing, the original target is hidden as the
   3752   // ShadowTarget and operations on the original actually affect the
   3753   // shadowing target.
   3754   //
   3755   // We should probably try to unify the escaping targets and the return
   3756   // target.
   3757   int nof_escapes = node->escaping_targets()->length();
   3758   List<ShadowTarget*> shadows(1 + nof_escapes);
   3759 
   3760   // Add the shadow target for the function return.
   3761   static const int kReturnShadowIndex = 0;
   3762   shadows.Add(new ShadowTarget(&function_return_));
   3763   bool function_return_was_shadowed = function_return_is_shadowed_;
   3764   function_return_is_shadowed_ = true;
   3765   ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
   3766 
   3767   // Add the remaining shadow targets.
   3768   for (int i = 0; i < nof_escapes; i++) {
   3769     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
   3770   }
   3771 
   3772   // Generate code for the statements in the try block.
   3773   VisitStatementsAndSpill(node->try_block()->statements());
   3774 
   3775   // Stop the introduced shadowing and count the number of required unlinks.
   3776   // After shadowing stops, the original targets are unshadowed and the
   3777   // ShadowTargets represent the formerly shadowing targets.
   3778   bool has_unlinks = false;
   3779   for (int i = 0; i < shadows.length(); i++) {
   3780     shadows[i]->StopShadowing();
   3781     has_unlinks = has_unlinks || shadows[i]->is_linked();
   3782   }
   3783   function_return_is_shadowed_ = function_return_was_shadowed;
   3784 
   3785   // Get an external reference to the handler address.
   3786   ExternalReference handler_address(Top::k_handler_address);
   3787 
   3788   // Make sure that there's nothing left on the stack above the
   3789   // handler structure.
   3790   if (FLAG_debug_code) {
   3791     __ mov(eax, Operand::StaticVariable(handler_address));
   3792     __ cmp(esp, Operand(eax));
   3793     __ Assert(equal, "stack pointer should point to top handler");
   3794   }
   3795 
   3796   // If we can fall off the end of the try block, unlink from try chain.
   3797   if (has_valid_frame()) {
   3798     // The next handler address is on top of the frame.  Unlink from
   3799     // the handler list and drop the rest of this handler from the
   3800     // frame.
   3801     ASSERT(StackHandlerConstants::kNextOffset == 0);
   3802     frame_->EmitPop(Operand::StaticVariable(handler_address));
   3803     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   3804     if (has_unlinks) {
   3805       exit.Jump();
   3806     }
   3807   }
   3808 
   3809   // Generate unlink code for the (formerly) shadowing targets that
   3810   // have been jumped to.  Deallocate each shadow target.
   3811   Result return_value;
   3812   for (int i = 0; i < shadows.length(); i++) {
   3813     if (shadows[i]->is_linked()) {
   3814       // Unlink from try chain; be careful not to destroy the TOS if
   3815       // there is one.
   3816       if (i == kReturnShadowIndex) {
   3817         shadows[i]->Bind(&return_value);
   3818         return_value.ToRegister(eax);
   3819       } else {
   3820         shadows[i]->Bind();
   3821       }
   3822       // Because we can be jumping here (to spilled code) from
   3823       // unspilled code, we need to reestablish a spilled frame at
   3824       // this block.
   3825       frame_->SpillAll();
   3826 
   3827       // Reload sp from the top handler, because some statements that we
   3828       // break from (eg, for...in) may have left stuff on the stack.
   3829       __ mov(esp, Operand::StaticVariable(handler_address));
   3830       frame_->Forget(frame_->height() - handler_height);
   3831 
   3832       ASSERT(StackHandlerConstants::kNextOffset == 0);
   3833       frame_->EmitPop(Operand::StaticVariable(handler_address));
   3834       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   3835 
   3836       if (i == kReturnShadowIndex) {
   3837         if (!function_return_is_shadowed_) frame_->PrepareForReturn();
   3838         shadows[i]->other_target()->Jump(&return_value);
   3839       } else {
   3840         shadows[i]->other_target()->Jump();
   3841       }
   3842     }
   3843   }
   3844 
   3845   exit.Bind();
   3846 }
   3847 
   3848 
   3849 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
   3850   ASSERT(!in_spilled_code());
   3851   VirtualFrame::SpilledScope spilled_scope;
   3852   Comment cmnt(masm_, "[ TryFinallyStatement");
   3853   CodeForStatementPosition(node);
   3854 
   3855   // State: Used to keep track of reason for entering the finally
   3856   // block. Should probably be extended to hold information for
   3857   // break/continue from within the try block.
   3858   enum { FALLING, THROWING, JUMPING };
   3859 
   3860   JumpTarget try_block;
   3861   JumpTarget finally_block;
   3862 
   3863   try_block.Call();
   3864 
   3865   frame_->EmitPush(eax);
   3866   // In case of thrown exceptions, this is where we continue.
   3867   __ Set(ecx, Immediate(Smi::FromInt(THROWING)));
   3868   finally_block.Jump();
   3869 
   3870   // --- Try block ---
   3871   try_block.Bind();
   3872 
   3873   frame_->PushTryHandler(TRY_FINALLY_HANDLER);
   3874   int handler_height = frame_->height();
   3875 
   3876   // Shadow the jump targets for all escapes from the try block, including
   3877   // returns.  During shadowing, the original target is hidden as the
   3878   // ShadowTarget and operations on the original actually affect the
   3879   // shadowing target.
   3880   //
   3881   // We should probably try to unify the escaping targets and the return
   3882   // target.
   3883   int nof_escapes = node->escaping_targets()->length();
   3884   List<ShadowTarget*> shadows(1 + nof_escapes);
   3885 
   3886   // Add the shadow target for the function return.
   3887   static const int kReturnShadowIndex = 0;
   3888   shadows.Add(new ShadowTarget(&function_return_));
   3889   bool function_return_was_shadowed = function_return_is_shadowed_;
   3890   function_return_is_shadowed_ = true;
   3891   ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
   3892 
   3893   // Add the remaining shadow targets.
   3894   for (int i = 0; i < nof_escapes; i++) {
   3895     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
   3896   }
   3897 
   3898   // Generate code for the statements in the try block.
   3899   VisitStatementsAndSpill(node->try_block()->statements());
   3900 
   3901   // Stop the introduced shadowing and count the number of required unlinks.
   3902   // After shadowing stops, the original targets are unshadowed and the
   3903   // ShadowTargets represent the formerly shadowing targets.
   3904   int nof_unlinks = 0;
   3905   for (int i = 0; i < shadows.length(); i++) {
   3906     shadows[i]->StopShadowing();
   3907     if (shadows[i]->is_linked()) nof_unlinks++;
   3908   }
   3909   function_return_is_shadowed_ = function_return_was_shadowed;
   3910 
   3911   // Get an external reference to the handler address.
   3912   ExternalReference handler_address(Top::k_handler_address);
   3913 
   3914   // If we can fall off the end of the try block, unlink from the try
   3915   // chain and set the state on the frame to FALLING.
   3916   if (has_valid_frame()) {
   3917     // The next handler address is on top of the frame.
   3918     ASSERT(StackHandlerConstants::kNextOffset == 0);
   3919     frame_->EmitPop(Operand::StaticVariable(handler_address));
   3920     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   3921 
   3922     // Fake a top of stack value (unneeded when FALLING) and set the
   3923     // state in ecx, then jump around the unlink blocks if any.
   3924     frame_->EmitPush(Immediate(Factory::undefined_value()));
   3925     __ Set(ecx, Immediate(Smi::FromInt(FALLING)));
   3926     if (nof_unlinks > 0) {
   3927       finally_block.Jump();
   3928     }
   3929   }
   3930 
   3931   // Generate code to unlink and set the state for the (formerly)
   3932   // shadowing targets that have been jumped to.
   3933   for (int i = 0; i < shadows.length(); i++) {
   3934     if (shadows[i]->is_linked()) {
   3935       // If we have come from the shadowed return, the return value is
   3936       // on the virtual frame.  We must preserve it until it is
   3937       // pushed.
   3938       if (i == kReturnShadowIndex) {
   3939         Result return_value;
   3940         shadows[i]->Bind(&return_value);
   3941         return_value.ToRegister(eax);
   3942       } else {
   3943         shadows[i]->Bind();
   3944       }
   3945       // Because we can be jumping here (to spilled code) from
   3946       // unspilled code, we need to reestablish a spilled frame at
   3947       // this block.
   3948       frame_->SpillAll();
   3949 
   3950       // Reload sp from the top handler, because some statements that
   3951       // we break from (eg, for...in) may have left stuff on the
   3952       // stack.
   3953       __ mov(esp, Operand::StaticVariable(handler_address));
   3954       frame_->Forget(frame_->height() - handler_height);
   3955 
   3956       // Unlink this handler and drop it from the frame.
   3957       ASSERT(StackHandlerConstants::kNextOffset == 0);
   3958       frame_->EmitPop(Operand::StaticVariable(handler_address));
   3959       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
   3960 
   3961       if (i == kReturnShadowIndex) {
   3962         // If this target shadowed the function return, materialize
   3963         // the return value on the stack.
   3964         frame_->EmitPush(eax);
   3965       } else {
   3966         // Fake TOS for targets that shadowed breaks and continues.
   3967         frame_->EmitPush(Immediate(Factory::undefined_value()));
   3968       }
   3969       __ Set(ecx, Immediate(Smi::FromInt(JUMPING + i)));
   3970       if (--nof_unlinks > 0) {
   3971         // If this is not the last unlink block, jump around the next.
   3972         finally_block.Jump();
   3973       }
   3974     }
   3975   }
   3976 
   3977   // --- Finally block ---
   3978   finally_block.Bind();
   3979 
   3980   // Push the state on the stack.
   3981   frame_->EmitPush(ecx);
   3982 
   3983   // We keep two elements on the stack - the (possibly faked) result
   3984   // and the state - while evaluating the finally block.
   3985   //
   3986   // Generate code for the statements in the finally block.
   3987   VisitStatementsAndSpill(node->finally_block()->statements());
   3988 
   3989   if (has_valid_frame()) {
   3990     // Restore state and return value or faked TOS.
   3991     frame_->EmitPop(ecx);
   3992     frame_->EmitPop(eax);
   3993   }
   3994 
   3995   // Generate code to jump to the right destination for all used
   3996   // formerly shadowing targets.  Deallocate each shadow target.
   3997   for (int i = 0; i < shadows.length(); i++) {
   3998     if (has_valid_frame() && shadows[i]->is_bound()) {
   3999       BreakTarget* original = shadows[i]->other_target();
   4000       __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i)));
   4001       if (i == kReturnShadowIndex) {
   4002         // The return value is (already) in eax.
   4003         Result return_value = allocator_->Allocate(eax);
   4004         ASSERT(return_value.is_valid());
   4005         if (function_return_is_shadowed_) {
   4006           original->Branch(equal, &return_value);
   4007         } else {
   4008           // Branch around the preparation for return which may emit
   4009           // code.
   4010           JumpTarget skip;
   4011           skip.Branch(not_equal);
   4012           frame_->PrepareForReturn();
   4013           original->Jump(&return_value);
   4014           skip.Bind();
   4015         }
   4016       } else {
   4017         original->Branch(equal);
   4018       }
   4019     }
   4020   }
   4021 
   4022   if (has_valid_frame()) {
   4023     // Check if we need to rethrow the exception.
   4024     JumpTarget exit;
   4025     __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING)));
   4026     exit.Branch(not_equal);
   4027 
   4028     // Rethrow exception.
   4029     frame_->EmitPush(eax);  // undo pop from above
   4030     frame_->CallRuntime(Runtime::kReThrow, 1);
   4031 
   4032     // Done.
   4033     exit.Bind();
   4034   }
   4035 }
   4036 
   4037 
   4038 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
   4039   ASSERT(!in_spilled_code());
   4040   Comment cmnt(masm_, "[ DebuggerStatement");
   4041   CodeForStatementPosition(node);
   4042 #ifdef ENABLE_DEBUGGER_SUPPORT
   4043   // Spill everything, even constants, to the frame.
   4044   frame_->SpillAll();
   4045 
   4046   frame_->DebugBreak();
   4047   // Ignore the return value.
   4048 #endif
   4049 }
   4050 
   4051 
   4052 Result CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
   4053   ASSERT(boilerplate->IsBoilerplate());
   4054 
   4055   // The inevitable call will sync frame elements to memory anyway, so
   4056   // we do it eagerly to allow us to push the arguments directly into
   4057   // place.
   4058   frame()->SyncRange(0, frame()->element_count() - 1);
   4059 
   4060   // Use the fast case closure allocation code that allocates in new
   4061   // space for nested functions that don't need literals cloning.
   4062   if (scope()->is_function_scope() && boilerplate->NumberOfLiterals() == 0) {
   4063     FastNewClosureStub stub;
   4064     frame()->EmitPush(Immediate(boilerplate));
   4065     return frame()->CallStub(&stub, 1);
   4066   } else {
   4067     // Call the runtime to instantiate the function boilerplate
   4068     // object.
   4069     frame()->EmitPush(esi);
   4070     frame()->EmitPush(Immediate(boilerplate));
   4071     return frame()->CallRuntime(Runtime::kNewClosure, 2);
   4072   }
   4073 }
   4074 
   4075 
   4076 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
   4077   Comment cmnt(masm_, "[ FunctionLiteral");
   4078 
   4079   // Build the function boilerplate and instantiate it.
   4080   Handle<JSFunction> boilerplate =
   4081       Compiler::BuildBoilerplate(node, script(), this);
   4082   // Check for stack-overflow exception.
   4083   if (HasStackOverflow()) return;
   4084   Result result = InstantiateBoilerplate(boilerplate);
   4085   frame()->Push(&result);
   4086 }
   4087 
   4088 
   4089 void CodeGenerator::VisitFunctionBoilerplateLiteral(
   4090     FunctionBoilerplateLiteral* node) {
   4091   Comment cmnt(masm_, "[ FunctionBoilerplateLiteral");
   4092   Result result = InstantiateBoilerplate(node->boilerplate());
   4093   frame()->Push(&result);
   4094 }
   4095 
   4096 
   4097 void CodeGenerator::VisitConditional(Conditional* node) {
   4098   Comment cmnt(masm_, "[ Conditional");
   4099   JumpTarget then;
   4100   JumpTarget else_;
   4101   JumpTarget exit;
   4102   ControlDestination dest(&then, &else_, true);
   4103   LoadCondition(node->condition(), &dest, true);
   4104 
   4105   if (dest.false_was_fall_through()) {
   4106     // The else target was bound, so we compile the else part first.
   4107     Load(node->else_expression());
   4108 
   4109     if (then.is_linked()) {
   4110       exit.Jump();
   4111       then.Bind();
   4112       Load(node->then_expression());
   4113     }
   4114   } else {
   4115     // The then target was bound, so we compile the then part first.
   4116     Load(node->then_expression());
   4117 
   4118     if (else_.is_linked()) {
   4119       exit.Jump();
   4120       else_.Bind();
   4121       Load(node->else_expression());
   4122     }
   4123   }
   4124 
   4125   exit.Bind();
   4126 }
   4127 
   4128 
   4129 Result CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
   4130   Result result;
   4131   if (slot->type() == Slot::LOOKUP) {
   4132     ASSERT(slot->var()->is_dynamic());
   4133     JumpTarget slow;
   4134     JumpTarget done;
   4135 
   4136     // Generate fast-case code for variables that might be shadowed by
   4137     // eval-introduced variables.  Eval is used a lot without
   4138     // introducing variables.  In those cases, we do not want to
   4139     // perform a runtime call for all variables in the scope
   4140     // containing the eval.
   4141     if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
   4142       result = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow);
   4143       // If there was no control flow to slow, we can exit early.
   4144       if (!slow.is_linked()) return result;
   4145       done.Jump(&result);
   4146 
   4147     } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
   4148       Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
   4149       // Only generate the fast case for locals that rewrite to slots.
   4150       // This rules out argument loads.
   4151       if (potential_slot != NULL) {
   4152         // Allocate a fresh register to use as a temp in
   4153         // ContextSlotOperandCheckExtensions and to hold the result
   4154         // value.
   4155         result = allocator()->Allocate();
   4156         ASSERT(result.is_valid());
   4157         __ mov(result.reg(),
   4158                ContextSlotOperandCheckExtensions(potential_slot,
   4159                                                  result,
   4160                                                  &slow));
   4161         if (potential_slot->var()->mode() == Variable::CONST) {
   4162           __ cmp(result.reg(), Factory::the_hole_value());
   4163           done.Branch(not_equal, &result);
   4164           __ mov(result.reg(), Factory::undefined_value());
   4165         }
   4166         // There is always control flow to slow from
   4167         // ContextSlotOperandCheckExtensions so we have to jump around
   4168         // it.
   4169         done.Jump(&result);
   4170       }
   4171     }
   4172 
   4173     slow.Bind();
   4174     // A runtime call is inevitable.  We eagerly sync frame elements
   4175     // to memory so that we can push the arguments directly into place
   4176     // on top of the frame.
   4177     frame()->SyncRange(0, frame()->element_count() - 1);
   4178     frame()->EmitPush(esi);
   4179     frame()->EmitPush(Immediate(slot->var()->name()));
   4180     if (typeof_state == INSIDE_TYPEOF) {
   4181       result =
   4182           frame()->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
   4183     } else {
   4184       result = frame()->CallRuntime(Runtime::kLoadContextSlot, 2);
   4185     }
   4186 
   4187     done.Bind(&result);
   4188     return result;
   4189 
   4190   } else if (slot->var()->mode() == Variable::CONST) {
   4191     // Const slots may contain 'the hole' value (the constant hasn't been
   4192     // initialized yet) which needs to be converted into the 'undefined'
   4193     // value.
   4194     //
   4195     // We currently spill the virtual frame because constants use the
   4196     // potentially unsafe direct-frame access of SlotOperand.
   4197     VirtualFrame::SpilledScope spilled_scope;
   4198     Comment cmnt(masm_, "[ Load const");
   4199     Label exit;
   4200     __ mov(ecx, SlotOperand(slot, ecx));
   4201     __ cmp(ecx, Factory::the_hole_value());
   4202     __ j(not_equal, &exit);
   4203     __ mov(ecx, Factory::undefined_value());
   4204     __ bind(&exit);
   4205     return Result(ecx);
   4206 
   4207   } else if (slot->type() == Slot::PARAMETER) {
   4208     frame()->PushParameterAt(slot->index());
   4209     return frame()->Pop();
   4210 
   4211   } else if (slot->type() == Slot::LOCAL) {
   4212     frame()->PushLocalAt(slot->index());
   4213     return frame()->Pop();
   4214 
   4215   } else {
   4216     // The other remaining slot types (LOOKUP and GLOBAL) cannot reach
   4217     // here.
   4218     //
   4219     // The use of SlotOperand below is safe for an unspilled frame
   4220     // because it will always be a context slot.
   4221     ASSERT(slot->type() == Slot::CONTEXT);
   4222     result = allocator()->Allocate();
   4223     ASSERT(result.is_valid());
   4224     __ mov(result.reg(), SlotOperand(slot, result.reg()));
   4225     return result;
   4226   }
   4227 }
   4228 
   4229 
   4230 Result CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot,
   4231                                                     TypeofState state) {
   4232   Result result = LoadFromSlot(slot, state);
   4233 
   4234   // Bail out quickly if we're not using lazy arguments allocation.
   4235   if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return result;
   4236 
   4237   // ... or if the slot isn't a non-parameter arguments slot.
   4238   if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return result;
   4239 
   4240   // If the loaded value is a constant, we know if the arguments
   4241   // object has been lazily loaded yet.
   4242   if (result.is_constant()) {
   4243     if (result.handle()->IsTheHole()) {
   4244       result.Unuse();
   4245       return StoreArgumentsObject(false);
   4246     } else {
   4247       return result;
   4248     }
   4249   }
   4250 
   4251   // The loaded value is in a register. If it is the sentinel that
   4252   // indicates that we haven't loaded the arguments object yet, we
   4253   // need to do it now.
   4254   JumpTarget exit;
   4255   __ cmp(Operand(result.reg()), Immediate(Factory::the_hole_value()));
   4256   exit.Branch(not_equal, &result);
   4257 
   4258   result.Unuse();
   4259   result = StoreArgumentsObject(false);
   4260   exit.Bind(&result);
   4261   return result;
   4262 }
   4263 
   4264 
   4265 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions(
   4266     Slot* slot,
   4267     TypeofState typeof_state,
   4268     JumpTarget* slow) {
   4269   // Check that no extension objects have been created by calls to
   4270   // eval from the current scope to the global scope.
   4271   Register context = esi;
   4272   Result tmp = allocator_->Allocate();
   4273   ASSERT(tmp.is_valid());  // All non-reserved registers were available.
   4274 
   4275   Scope* s = scope();
   4276   while (s != NULL) {
   4277     if (s->num_heap_slots() > 0) {
   4278       if (s->calls_eval()) {
   4279         // Check that extension is NULL.
   4280         __ cmp(ContextOperand(context, Context::EXTENSION_INDEX),
   4281                Immediate(0));
   4282         slow->Branch(not_equal, not_taken);
   4283       }
   4284       // Load next context in chain.
   4285       __ mov(tmp.reg(), ContextOperand(context, Context::CLOSURE_INDEX));
   4286       __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
   4287       context = tmp.reg();
   4288     }
   4289     // If no outer scope calls eval, we do not need to check more
   4290     // context extensions.  If we have reached an eval scope, we check
   4291     // all extensions from this point.
   4292     if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
   4293     s = s->outer_scope();
   4294   }
   4295 
   4296   if (s != NULL && s->is_eval_scope()) {
   4297     // Loop up the context chain.  There is no frame effect so it is
   4298     // safe to use raw labels here.
   4299     Label next, fast;
   4300     if (!context.is(tmp.reg())) {
   4301       __ mov(tmp.reg(), context);
   4302     }
   4303     __ bind(&next);
   4304     // Terminate at global context.
   4305     __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
   4306            Immediate(Factory::global_context_map()));
   4307     __ j(equal, &fast);
   4308     // Check that extension is NULL.
   4309     __ cmp(ContextOperand(tmp.reg(), Context::EXTENSION_INDEX), Immediate(0));
   4310     slow->Branch(not_equal, not_taken);
   4311     // Load next context in chain.
   4312     __ mov(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX));
   4313     __ mov(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
   4314     __ jmp(&next);
   4315     __ bind(&fast);
   4316   }
   4317   tmp.Unuse();
   4318 
   4319   // All extension objects were empty and it is safe to use a global
   4320   // load IC call.
   4321   // The register allocator prefers eax if it is free, so the code generator
   4322   // will load the global object directly into eax, which is where the LoadIC
   4323   // expects it.
   4324   frame_->Spill(eax);
   4325   LoadGlobal();
   4326   frame_->Push(slot->var()->name());
   4327   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
   4328                          ? RelocInfo::CODE_TARGET
   4329                          : RelocInfo::CODE_TARGET_CONTEXT;
   4330   Result answer = frame_->CallLoadIC(mode);
   4331   // A test eax instruction following the call signals that the inobject
   4332   // property case was inlined.  Ensure that there is not a test eax
   4333   // instruction here.
   4334   __ nop();
   4335   return answer;
   4336 }
   4337 
   4338 
   4339 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
   4340   if (slot->type() == Slot::LOOKUP) {
   4341     ASSERT(slot->var()->is_dynamic());
   4342 
   4343     // For now, just do a runtime call.  Since the call is inevitable,
   4344     // we eagerly sync the virtual frame so we can directly push the
   4345     // arguments into place.
   4346     frame_->SyncRange(0, frame_->element_count() - 1);
   4347 
   4348     frame_->EmitPush(esi);
   4349     frame_->EmitPush(Immediate(slot->var()->name()));
   4350 
   4351     Result value;
   4352     if (init_state == CONST_INIT) {
   4353       // Same as the case for a normal store, but ignores attribute
   4354       // (e.g. READ_ONLY) of context slot so that we can initialize const
   4355       // properties (introduced via eval("const foo = (some expr);")). Also,
   4356       // uses the current function context instead of the top context.
   4357       //
   4358       // Note that we must declare the foo upon entry of eval(), via a
   4359       // context slot declaration, but we cannot initialize it at the same
   4360       // time, because the const declaration may be at the end of the eval
   4361       // code (sigh...) and the const variable may have been used before
   4362       // (where its value is 'undefined'). Thus, we can only do the
   4363       // initialization when we actually encounter the expression and when
   4364       // the expression operands are defined and valid, and thus we need the
   4365       // split into 2 operations: declaration of the context slot followed
   4366       // by initialization.
   4367       value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
   4368     } else {
   4369       value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3);
   4370     }
   4371     // Storing a variable must keep the (new) value on the expression
   4372     // stack. This is necessary for compiling chained assignment
   4373     // expressions.
   4374     frame_->Push(&value);
   4375 
   4376   } else {
   4377     ASSERT(!slot->var()->is_dynamic());
   4378 
   4379     JumpTarget exit;
   4380     if (init_state == CONST_INIT) {
   4381       ASSERT(slot->var()->mode() == Variable::CONST);
   4382       // Only the first const initialization must be executed (the slot
   4383       // still contains 'the hole' value). When the assignment is executed,
   4384       // the code is identical to a normal store (see below).
   4385       //
   4386       // We spill the frame in the code below because the direct-frame
   4387       // access of SlotOperand is potentially unsafe with an unspilled
   4388       // frame.
   4389       VirtualFrame::SpilledScope spilled_scope;
   4390       Comment cmnt(masm_, "[ Init const");
   4391       __ mov(ecx, SlotOperand(slot, ecx));
   4392       __ cmp(ecx, Factory::the_hole_value());
   4393       exit.Branch(not_equal);
   4394     }
   4395 
   4396     // We must execute the store.  Storing a variable must keep the (new)
   4397     // value on the stack. This is necessary for compiling assignment
   4398     // expressions.
   4399     //
   4400     // Note: We will reach here even with slot->var()->mode() ==
   4401     // Variable::CONST because of const declarations which will initialize
   4402     // consts to 'the hole' value and by doing so, end up calling this code.
   4403     if (slot->type() == Slot::PARAMETER) {
   4404       frame_->StoreToParameterAt(slot->index());
   4405     } else if (slot->type() == Slot::LOCAL) {
   4406       frame_->StoreToLocalAt(slot->index());
   4407     } else {
   4408       // The other slot types (LOOKUP and GLOBAL) cannot reach here.
   4409       //
   4410       // The use of SlotOperand below is safe for an unspilled frame
   4411       // because the slot is a context slot.
   4412       ASSERT(slot->type() == Slot::CONTEXT);
   4413       frame_->Dup();
   4414       Result value = frame_->Pop();
   4415       value.ToRegister();
   4416       Result start = allocator_->Allocate();
   4417       ASSERT(start.is_valid());
   4418       __ mov(SlotOperand(slot, start.reg()), value.reg());
   4419       // RecordWrite may destroy the value registers.
   4420       //
   4421       // TODO(204): Avoid actually spilling when the value is not
   4422       // needed (probably the common case).
   4423       frame_->Spill(value.reg());
   4424       int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
   4425       Result temp = allocator_->Allocate();
   4426       ASSERT(temp.is_valid());
   4427       __ RecordWrite(start.reg(), offset, value.reg(), temp.reg());
   4428       // The results start, value, and temp are unused by going out of
   4429       // scope.
   4430     }
   4431 
   4432     exit.Bind();
   4433   }
   4434 }
   4435 
   4436 
   4437 void CodeGenerator::VisitSlot(Slot* node) {
   4438   Comment cmnt(masm_, "[ Slot");
   4439   Result result = LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF);
   4440   frame()->Push(&result);
   4441 }
   4442 
   4443 
   4444 void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
   4445   Comment cmnt(masm_, "[ VariableProxy");
   4446   Variable* var = node->var();
   4447   Expression* expr = var->rewrite();
   4448   if (expr != NULL) {
   4449     Visit(expr);
   4450   } else {
   4451     ASSERT(var->is_global());
   4452     Reference ref(this, node);
   4453     ref.GetValue();
   4454   }
   4455 }
   4456 
   4457 
   4458 void CodeGenerator::VisitLiteral(Literal* node) {
   4459   Comment cmnt(masm_, "[ Literal");
   4460   frame_->Push(node->handle());
   4461 }
   4462 
   4463 
   4464 void CodeGenerator::PushUnsafeSmi(Handle<Object> value) {
   4465   ASSERT(value->IsSmi());
   4466   int bits = reinterpret_cast<int>(*value);
   4467   __ push(Immediate(bits & 0x0000FFFF));
   4468   __ or_(Operand(esp, 0), Immediate(bits & 0xFFFF0000));
   4469 }
   4470 
   4471 
   4472 void CodeGenerator::StoreUnsafeSmiToLocal(int offset, Handle<Object> value) {
   4473   ASSERT(value->IsSmi());
   4474   int bits = reinterpret_cast<int>(*value);
   4475   __ mov(Operand(ebp, offset), Immediate(bits & 0x0000FFFF));
   4476   __ or_(Operand(ebp, offset), Immediate(bits & 0xFFFF0000));
   4477 }
   4478 
   4479 
   4480 void CodeGenerator::MoveUnsafeSmi(Register target, Handle<Object> value) {
   4481   ASSERT(target.is_valid());
   4482   ASSERT(value->IsSmi());
   4483   int bits = reinterpret_cast<int>(*value);
   4484   __ Set(target, Immediate(bits & 0x0000FFFF));
   4485   __ or_(target, bits & 0xFFFF0000);
   4486 }
   4487 
   4488 
   4489 bool CodeGenerator::IsUnsafeSmi(Handle<Object> value) {
   4490   if (!value->IsSmi()) return false;
   4491   int int_value = Smi::cast(*value)->value();
   4492   return !is_intn(int_value, kMaxSmiInlinedBits);
   4493 }
   4494 
   4495 
   4496 // Materialize the regexp literal 'node' in the literals array
   4497 // 'literals' of the function.  Leave the regexp boilerplate in
   4498 // 'boilerplate'.
   4499 class DeferredRegExpLiteral: public DeferredCode {
   4500  public:
   4501   DeferredRegExpLiteral(Register boilerplate,
   4502                         Register literals,
   4503                         RegExpLiteral* node)
   4504       : boilerplate_(boilerplate), literals_(literals), node_(node) {
   4505     set_comment("[ DeferredRegExpLiteral");
   4506   }
   4507 
   4508   void Generate();
   4509 
   4510  private:
   4511   Register boilerplate_;
   4512   Register literals_;
   4513   RegExpLiteral* node_;
   4514 };
   4515 
   4516 
   4517 void DeferredRegExpLiteral::Generate() {
   4518   // Since the entry is undefined we call the runtime system to
   4519   // compute the literal.
   4520   // Literal array (0).
   4521   __ push(literals_);
   4522   // Literal index (1).
   4523   __ push(Immediate(Smi::FromInt(node_->literal_index())));
   4524   // RegExp pattern (2).
   4525   __ push(Immediate(node_->pattern()));
   4526   // RegExp flags (3).
   4527   __ push(Immediate(node_->flags()));
   4528   __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
   4529   if (!boilerplate_.is(eax)) __ mov(boilerplate_, eax);
   4530 }
   4531 
   4532 
   4533 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
   4534   Comment cmnt(masm_, "[ RegExp Literal");
   4535 
   4536   // Retrieve the literals array and check the allocated entry.  Begin
   4537   // with a writable copy of the function of this activation in a
   4538   // register.
   4539   frame_->PushFunction();
   4540   Result literals = frame_->Pop();
   4541   literals.ToRegister();
   4542   frame_->Spill(literals.reg());
   4543 
   4544   // Load the literals array of the function.
   4545   __ mov(literals.reg(),
   4546          FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
   4547 
   4548   // Load the literal at the ast saved index.
   4549   Result boilerplate = allocator_->Allocate();
   4550   ASSERT(boilerplate.is_valid());
   4551   int literal_offset =
   4552       FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
   4553   __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset));
   4554 
   4555   // Check whether we need to materialize the RegExp object.  If so,
   4556   // jump to the deferred code passing the literals array.
   4557   DeferredRegExpLiteral* deferred =
   4558       new DeferredRegExpLiteral(boilerplate.reg(), literals.reg(), node);
   4559   __ cmp(boilerplate.reg(), Factory::undefined_value());
   4560   deferred->Branch(equal);
   4561   deferred->BindExit();
   4562   literals.Unuse();
   4563 
   4564   // Push the boilerplate object.
   4565   frame_->Push(&boilerplate);
   4566 }
   4567 
   4568 
   4569 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
   4570   Comment cmnt(masm_, "[ ObjectLiteral");
   4571 
   4572   // Load a writable copy of the function of this activation in a
   4573   // register.
   4574   frame_->PushFunction();
   4575   Result literals = frame_->Pop();
   4576   literals.ToRegister();
   4577   frame_->Spill(literals.reg());
   4578 
   4579   // Load the literals array of the function.
   4580   __ mov(literals.reg(),
   4581          FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
   4582   // Literal array.
   4583   frame_->Push(&literals);
   4584   // Literal index.
   4585   frame_->Push(Smi::FromInt(node->literal_index()));
   4586   // Constant properties.
   4587   frame_->Push(node->constant_properties());
   4588   Result clone;
   4589   if (node->depth() > 1) {
   4590     clone = frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3);
   4591   } else {
   4592     clone = frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
   4593   }
   4594   frame_->Push(&clone);
   4595 
   4596   for (int i = 0; i < node->properties()->length(); i++) {
   4597     ObjectLiteral::Property* property = node->properties()->at(i);
   4598     switch (property->kind()) {
   4599       case ObjectLiteral::Property::CONSTANT:
   4600         break;
   4601       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   4602         if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
   4603         // else fall through.
   4604       case ObjectLiteral::Property::COMPUTED: {
   4605         Handle<Object> key(property->key()->handle());
   4606         if (key->IsSymbol()) {
   4607           // Duplicate the object as the IC receiver.
   4608           frame_->Dup();
   4609           Load(property->value());
   4610           Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
   4611           dummy.Unuse();
   4612           break;
   4613         }
   4614         // Fall through
   4615       }
   4616       case ObjectLiteral::Property::PROTOTYPE: {
   4617         // Duplicate the object as an argument to the runtime call.
   4618         frame_->Dup();
   4619         Load(property->key());
   4620         Load(property->value());
   4621         Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
   4622         // Ignore the result.
   4623         break;
   4624       }
   4625       case ObjectLiteral::Property::SETTER: {
   4626         // Duplicate the object as an argument to the runtime call.
   4627         frame_->Dup();
   4628         Load(property->key());
   4629         frame_->Push(Smi::FromInt(1));
   4630         Load(property->value());
   4631         Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4);
   4632         // Ignore the result.
   4633         break;
   4634       }
   4635       case ObjectLiteral::Property::GETTER: {
   4636         // Duplicate the object as an argument to the runtime call.
   4637         frame_->Dup();
   4638         Load(property->key());
   4639         frame_->Push(Smi::FromInt(0));
   4640         Load(property->value());
   4641         Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4);
   4642         // Ignore the result.
   4643         break;
   4644       }
   4645       default: UNREACHABLE();
   4646     }
   4647   }
   4648 }
   4649 
   4650 
   4651 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
   4652   Comment cmnt(masm_, "[ ArrayLiteral");
   4653 
   4654   // Load a writable copy of the function of this activation in a
   4655   // register.
   4656   frame_->PushFunction();
   4657   Result literals = frame_->Pop();
   4658   literals.ToRegister();
   4659   frame_->Spill(literals.reg());
   4660 
   4661   // Load the literals array of the function.
   4662   __ mov(literals.reg(),
   4663          FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
   4664 
   4665   frame_->Push(&literals);
   4666   frame_->Push(Smi::FromInt(node->literal_index()));
   4667   frame_->Push(node->constant_elements());
   4668   int length = node->values()->length();
   4669   Result clone;
   4670   if (node->depth() > 1) {
   4671     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
   4672   } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
   4673     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
   4674   } else {
   4675     FastCloneShallowArrayStub stub(length);
   4676     clone = frame_->CallStub(&stub, 3);
   4677   }
   4678   frame_->Push(&clone);
   4679 
   4680   // Generate code to set the elements in the array that are not
   4681   // literals.
   4682   for (int i = 0; i < length; i++) {
   4683     Expression* value = node->values()->at(i);
   4684 
   4685     // If value is a literal the property value is already set in the
   4686     // boilerplate object.
   4687     if (value->AsLiteral() != NULL) continue;
   4688     // If value is a materialized literal the property value is already set
   4689     // in the boilerplate object if it is simple.
   4690     if (CompileTimeValue::IsCompileTimeValue(value)) continue;
   4691 
   4692     // The property must be set by generated code.
   4693     Load(value);
   4694 
   4695     // Get the property value off the stack.
   4696     Result prop_value = frame_->Pop();
   4697     prop_value.ToRegister();
   4698 
   4699     // Fetch the array literal while leaving a copy on the stack and
   4700     // use it to get the elements array.
   4701     frame_->Dup();
   4702     Result elements = frame_->Pop();
   4703     elements.ToRegister();
   4704     frame_->Spill(elements.reg());
   4705     // Get the elements array.
   4706     __ mov(elements.reg(),
   4707            FieldOperand(elements.reg(), JSObject::kElementsOffset));
   4708 
   4709     // Write to the indexed properties array.
   4710     int offset = i * kPointerSize + FixedArray::kHeaderSize;
   4711     __ mov(FieldOperand(elements.reg(), offset), prop_value.reg());
   4712 
   4713     // Update the write barrier for the array address.
   4714     frame_->Spill(prop_value.reg());  // Overwritten by the write barrier.
   4715     Result scratch = allocator_->Allocate();
   4716     ASSERT(scratch.is_valid());
   4717     __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg());
   4718   }
   4719 }
   4720 
   4721 
   4722 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
   4723   ASSERT(!in_spilled_code());
   4724   // Call runtime routine to allocate the catch extension object and
   4725   // assign the exception value to the catch variable.
   4726   Comment cmnt(masm_, "[ CatchExtensionObject");
   4727   Load(node->key());
   4728   Load(node->value());
   4729   Result result =
   4730       frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
   4731   frame_->Push(&result);
   4732 }
   4733 
   4734 
   4735 void CodeGenerator::EmitSlotAssignment(Assignment* node) {
   4736 #ifdef DEBUG
   4737   int original_height = frame()->height();
   4738 #endif
   4739   Comment cmnt(masm(), "[ Variable Assignment");
   4740   Variable* var = node->target()->AsVariableProxy()->AsVariable();
   4741   ASSERT(var != NULL);
   4742   Slot* slot = var->slot();
   4743   ASSERT(slot != NULL);
   4744 
   4745   // Evaluate the right-hand side.
   4746   if (node->is_compound()) {
   4747     Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
   4748     frame()->Push(&result);
   4749     Load(node->value());
   4750 
   4751     bool overwrite_value =
   4752         (node->value()->AsBinaryOperation() != NULL &&
   4753          node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
   4754     GenericBinaryOperation(node->binary_op(),
   4755                            node->type(),
   4756                            overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
   4757   } else {
   4758     Load(node->value());
   4759   }
   4760 
   4761   // Perform the assignment.
   4762   if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
   4763     CodeForSourcePosition(node->position());
   4764     StoreToSlot(slot,
   4765                 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
   4766   }
   4767   ASSERT(frame()->height() == original_height + 1);
   4768 }
   4769 
   4770 
   4771 void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
   4772 #ifdef DEBUG
   4773   int original_height = frame()->height();
   4774 #endif
   4775   Comment cmnt(masm(), "[ Named Property Assignment");
   4776   Variable* var = node->target()->AsVariableProxy()->AsVariable();
   4777   Property* prop = node->target()->AsProperty();
   4778   ASSERT(var == NULL || (prop == NULL && var->is_global()));
   4779 
   4780   // Initialize name and evaluate the receiver subexpression if necessary.
   4781   Handle<String> name;
   4782   bool is_trivial_receiver = false;
   4783   if (var != NULL) {
   4784     name = var->name();
   4785   } else {
   4786     Literal* lit = prop->key()->AsLiteral();
   4787     ASSERT_NOT_NULL(lit);
   4788     name = Handle<String>::cast(lit->handle());
   4789     // Do not materialize the receiver on the frame if it is trivial.
   4790     is_trivial_receiver = prop->obj()->IsTrivial();
   4791     if (!is_trivial_receiver) Load(prop->obj());
   4792   }
   4793 
   4794   if (node->starts_initialization_block()) {
   4795     ASSERT_EQ(NULL, var);
   4796     // Change to slow case in the beginning of an initialization block to
   4797     // avoid the quadratic behavior of repeatedly adding fast properties.
   4798     if (is_trivial_receiver) {
   4799       frame()->Push(prop->obj());
   4800     } else {
   4801       frame()->Dup();
   4802     }
   4803     Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1);
   4804   }
   4805 
   4806   if (node->ends_initialization_block() && !is_trivial_receiver) {
   4807     // Add an extra copy of the receiver to the frame, so that it can be
   4808     // converted back to fast case after the assignment.
   4809     frame()->Dup();
   4810   }
   4811 
   4812   // Evaluate the right-hand side.
   4813   if (node->is_compound()) {
   4814     if (is_trivial_receiver) {
   4815       frame()->Push(prop->obj());
   4816     } else if (var != NULL) {
   4817       // The LoadIC stub expects the object in eax.
   4818       // Freeing eax causes the code generator to load the global into it.
   4819       frame_->Spill(eax);
   4820       LoadGlobal();
   4821     } else {
   4822       frame()->Dup();
   4823     }
   4824     Result value = EmitNamedLoad(name, var != NULL);
   4825     frame()->Push(&value);
   4826     Load(node->value());
   4827 
   4828     bool overwrite_value =
   4829         (node->value()->AsBinaryOperation() != NULL &&
   4830          node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
   4831     GenericBinaryOperation(node->binary_op(),
   4832                            node->type(),
   4833                            overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
   4834   } else {
   4835     Load(node->value());
   4836   }
   4837 
   4838   // Perform the assignment.  It is safe to ignore constants here.
   4839   ASSERT(var == NULL || var->mode() != Variable::CONST);
   4840   ASSERT_NE(Token::INIT_CONST, node->op());
   4841   if (is_trivial_receiver) {
   4842     Result value = frame()->Pop();
   4843     frame()->Push(prop->obj());
   4844     frame()->Push(&value);
   4845   }
   4846   CodeForSourcePosition(node->position());
   4847   bool is_contextual = (var != NULL);
   4848   Result answer = EmitNamedStore(name, is_contextual);
   4849   frame()->Push(&answer);
   4850 
   4851   if (node->ends_initialization_block()) {
   4852     ASSERT_EQ(NULL, var);
   4853     // The argument to the runtime call is the receiver.
   4854     if (is_trivial_receiver) {
   4855       frame()->Push(prop->obj());
   4856     } else {
   4857       // A copy of the receiver is below the value of the assignment.  Swap
   4858       // the receiver and the value of the assignment expression.
   4859       Result result = frame()->Pop();
   4860       Result receiver = frame()->Pop();
   4861       frame()->Push(&result);
   4862       frame()->Push(&receiver);
   4863     }
   4864     Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
   4865   }
   4866 
   4867   ASSERT_EQ(frame()->height(), original_height + 1);
   4868 }
   4869 
   4870 
   4871 void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
   4872 #ifdef DEBUG
   4873   int original_height = frame()->height();
   4874 #endif
   4875   Comment cmnt(masm_, "[ Named Property Assignment");
   4876   Property* prop = node->target()->AsProperty();
   4877   ASSERT_NOT_NULL(prop);
   4878 
   4879   // Evaluate the receiver subexpression.
   4880   Load(prop->obj());
   4881 
   4882   if (node->starts_initialization_block()) {
   4883     // Change to slow case in the beginning of an initialization block to
   4884     // avoid the quadratic behavior of repeatedly adding fast properties.
   4885     frame_->Dup();
   4886     Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
   4887   }
   4888 
   4889   if (node->ends_initialization_block()) {
   4890     // Add an extra copy of the receiver to the frame, so that it can be
   4891     // converted back to fast case after the assignment.
   4892     frame_->Dup();
   4893   }
   4894 
   4895   // Evaluate the key subexpression.
   4896   Load(prop->key());
   4897 
   4898   // Evaluate the right-hand side.
   4899   if (node->is_compound()) {
   4900     // Duplicate receiver and key.
   4901     frame()->PushElementAt(1);
   4902     frame()->PushElementAt(1);
   4903     Result value = EmitKeyedLoad();
   4904     frame()->Push(&value);
   4905     Load(node->value());
   4906 
   4907     bool overwrite_value =
   4908         (node->value()->AsBinaryOperation() != NULL &&
   4909          node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
   4910     GenericBinaryOperation(node->binary_op(),
   4911                            node->type(),
   4912                            overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
   4913   } else {
   4914     Load(node->value());
   4915   }
   4916 
   4917   // Perform the assignment.  It is safe to ignore constants here.
   4918   ASSERT(node->op() != Token::INIT_CONST);
   4919   CodeForSourcePosition(node->position());
   4920   Result answer = EmitKeyedStore(prop->key()->type());
   4921   frame()->Push(&answer);
   4922 
   4923   if (node->ends_initialization_block()) {
   4924     // The argument to the runtime call is the extra copy of the receiver,
   4925     // which is below the value of the assignment.  Swap the receiver and
   4926     // the value of the assignment expression.
   4927     Result result = frame()->Pop();
   4928     Result receiver = frame()->Pop();
   4929     frame()->Push(&result);
   4930     frame()->Push(&receiver);
   4931     Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
   4932   }
   4933 
   4934   ASSERT(frame()->height() == original_height + 1);
   4935 }
   4936 
   4937 
   4938 void CodeGenerator::VisitAssignment(Assignment* node) {
   4939 #ifdef DEBUG
   4940   int original_height = frame()->height();
   4941 #endif
   4942   Variable* var = node->target()->AsVariableProxy()->AsVariable();
   4943   Property* prop = node->target()->AsProperty();
   4944 
   4945   if (var != NULL && !var->is_global()) {
   4946     EmitSlotAssignment(node);
   4947 
   4948   } else if ((prop != NULL && prop->key()->IsPropertyName()) ||
   4949              (var != NULL && var->is_global())) {
   4950     // Properties whose keys are property names and global variables are
   4951     // treated as named property references.  We do not need to consider
   4952     // global 'this' because it is not a valid left-hand side.
   4953     EmitNamedPropertyAssignment(node);
   4954 
   4955   } else if (prop != NULL) {
   4956     // Other properties (including rewritten parameters for a function that
   4957     // uses arguments) are keyed property assignments.
   4958     EmitKeyedPropertyAssignment(node);
   4959 
   4960   } else {
   4961     // Invalid left-hand side.
   4962     Load(node->target());
   4963     Result result = frame()->CallRuntime(Runtime::kThrowReferenceError, 1);
   4964     // The runtime call doesn't actually return but the code generator will
   4965     // still generate code and expects a certain frame height.
   4966     frame()->Push(&result);
   4967   }
   4968 
   4969   ASSERT(frame()->height() == original_height + 1);
   4970 }
   4971 
   4972 
   4973 void CodeGenerator::VisitThrow(Throw* node) {
   4974   Comment cmnt(masm_, "[ Throw");
   4975   Load(node->exception());
   4976   Result result = frame_->CallRuntime(Runtime::kThrow, 1);
   4977   frame_->Push(&result);
   4978 }
   4979 
   4980 
   4981 void CodeGenerator::VisitProperty(Property* node) {
   4982   Comment cmnt(masm_, "[ Property");
   4983   Reference property(this, node);
   4984   property.GetValue();
   4985 }
   4986 
   4987 
   4988 void CodeGenerator::VisitCall(Call* node) {
   4989   Comment cmnt(masm_, "[ Call");
   4990 
   4991   Expression* function = node->expression();
   4992   ZoneList<Expression*>* args = node->arguments();
   4993 
   4994   // Check if the function is a variable or a property.
   4995   Variable* var = function->AsVariableProxy()->AsVariable();
   4996   Property* property = function->AsProperty();
   4997 
   4998   // ------------------------------------------------------------------------
   4999   // Fast-case: Use inline caching.
   5000   // ---
   5001   // According to ECMA-262, section 11.2.3, page 44, the function to call
   5002   // must be resolved after the arguments have been evaluated. The IC code
   5003   // automatically handles this by loading the arguments before the function
   5004   // is resolved in cache misses (this also holds for megamorphic calls).
   5005   // ------------------------------------------------------------------------
   5006 
   5007   if (var != NULL && var->is_possibly_eval()) {
   5008     // ----------------------------------
   5009     // JavaScript example: 'eval(arg)'  // eval is not known to be shadowed
   5010     // ----------------------------------
   5011 
   5012     // In a call to eval, we first call %ResolvePossiblyDirectEval to
   5013     // resolve the function we need to call and the receiver of the
   5014     // call.  Then we call the resolved function using the given
   5015     // arguments.
   5016 
   5017     // Prepare the stack for the call to the resolved function.
   5018     Load(function);
   5019 
   5020     // Allocate a frame slot for the receiver.
   5021     frame_->Push(Factory::undefined_value());
   5022     int arg_count = args->length();
   5023     for (int i = 0; i < arg_count; i++) {
   5024       Load(args->at(i));
   5025     }
   5026 
   5027     // Prepare the stack for the call to ResolvePossiblyDirectEval.
   5028     frame_->PushElementAt(arg_count + 1);
   5029     if (arg_count > 0) {
   5030       frame_->PushElementAt(arg_count);
   5031     } else {
   5032       frame_->Push(Factory::undefined_value());
   5033     }
   5034 
   5035     // Push the receiver.
   5036     frame_->PushParameterAt(-1);
   5037 
   5038     // Resolve the call.
   5039     Result result =
   5040         frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
   5041 
   5042     // The runtime call returns a pair of values in eax (function) and
   5043     // edx (receiver). Touch up the stack with the right values.
   5044     Result receiver = allocator_->Allocate(edx);
   5045     frame_->SetElementAt(arg_count + 1, &result);
   5046     frame_->SetElementAt(arg_count, &receiver);
   5047     receiver.Unuse();
   5048 
   5049     // Call the function.
   5050     CodeForSourcePosition(node->position());
   5051     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
   5052     CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
   5053     result = frame_->CallStub(&call_function, arg_count + 1);
   5054 
   5055     // Restore the context and overwrite the function on the stack with
   5056     // the result.
   5057     frame_->RestoreContextRegister();
   5058     frame_->SetElementAt(0, &result);
   5059 
   5060   } else if (var != NULL && !var->is_this() && var->is_global()) {
   5061     // ----------------------------------
   5062     // JavaScript example: 'foo(1, 2, 3)'  // foo is global
   5063     // ----------------------------------
   5064 
   5065     // Pass the global object as the receiver and let the IC stub
   5066     // patch the stack to use the global proxy as 'this' in the
   5067     // invoked function.
   5068     LoadGlobal();
   5069 
   5070     // Load the arguments.
   5071     int arg_count = args->length();
   5072     for (int i = 0; i < arg_count; i++) {
   5073       Load(args->at(i));
   5074     }
   5075 
   5076     // Push the name of the function onto the frame.
   5077     frame_->Push(var->name());
   5078 
   5079     // Call the IC initialization code.
   5080     CodeForSourcePosition(node->position());
   5081     Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT,
   5082                                        arg_count,
   5083                                        loop_nesting());
   5084     frame_->RestoreContextRegister();
   5085     frame_->Push(&result);
   5086 
   5087   } else if (var != NULL && var->slot() != NULL &&
   5088              var->slot()->type() == Slot::LOOKUP) {
   5089     // ----------------------------------
   5090     // JavaScript example: 'with (obj) foo(1, 2, 3)'  // foo is in obj
   5091     // ----------------------------------
   5092 
   5093     // Load the function from the context.  Sync the frame so we can
   5094     // push the arguments directly into place.
   5095     frame_->SyncRange(0, frame_->element_count() - 1);
   5096     frame_->EmitPush(esi);
   5097     frame_->EmitPush(Immediate(var->name()));
   5098     frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
   5099     // The runtime call returns a pair of values in eax and edx.  The
   5100     // looked-up function is in eax and the receiver is in edx.  These
   5101     // register references are not ref counted here.  We spill them
   5102     // eagerly since they are arguments to an inevitable call (and are
   5103     // not sharable by the arguments).
   5104     ASSERT(!allocator()->is_used(eax));
   5105     frame_->EmitPush(eax);
   5106 
   5107     // Load the receiver.
   5108     ASSERT(!allocator()->is_used(edx));
   5109     frame_->EmitPush(edx);
   5110 
   5111     // Call the function.
   5112     CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
   5113 
   5114   } else if (property != NULL) {
   5115     // Check if the key is a literal string.
   5116     Literal* literal = property->key()->AsLiteral();
   5117 
   5118     if (literal != NULL && literal->handle()->IsSymbol()) {
   5119       // ------------------------------------------------------------------
   5120       // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
   5121       // ------------------------------------------------------------------
   5122 
   5123       Handle<String> name = Handle<String>::cast(literal->handle());
   5124 
   5125       if (ArgumentsMode() == LAZY_ARGUMENTS_ALLOCATION &&
   5126           name->IsEqualTo(CStrVector("apply")) &&
   5127           args->length() == 2 &&
   5128           args->at(1)->AsVariableProxy() != NULL &&
   5129           args->at(1)->AsVariableProxy()->IsArguments()) {
   5130         // Use the optimized Function.prototype.apply that avoids
   5131         // allocating lazily allocated arguments objects.
   5132         CallApplyLazy(property->obj(),
   5133                       args->at(0),
   5134                       args->at(1)->AsVariableProxy(),
   5135                       node->position());
   5136 
   5137       } else {
   5138         // Push the receiver onto the frame.
   5139         Load(property->obj());
   5140 
   5141         // Load the arguments.
   5142         int arg_count = args->length();
   5143         for (int i = 0; i < arg_count; i++) {
   5144           Load(args->at(i));
   5145         }
   5146 
   5147         // Push the name of the function onto the frame.
   5148         frame_->Push(name);
   5149 
   5150         // Call the IC initialization code.
   5151         CodeForSourcePosition(node->position());
   5152         Result result =
   5153             frame_->CallCallIC(RelocInfo::CODE_TARGET, arg_count,
   5154                                loop_nesting());
   5155         frame_->RestoreContextRegister();
   5156         frame_->Push(&result);
   5157       }
   5158 
   5159     } else {
   5160       // -------------------------------------------
   5161       // JavaScript example: 'array[index](1, 2, 3)'
   5162       // -------------------------------------------
   5163 
   5164       // Load the function to call from the property through a reference.
   5165 
   5166       // Pass receiver to called function.
   5167       if (property->is_synthetic()) {
   5168         Reference ref(this, property);
   5169         ref.GetValue();
   5170         // Use global object as receiver.
   5171         LoadGlobalReceiver();
   5172       } else {
   5173         Load(property->obj());
   5174         frame()->Dup();
   5175         Load(property->key());
   5176         Result function = EmitKeyedLoad();
   5177         Result receiver = frame_->Pop();
   5178         frame_->Push(&function);
   5179         frame_->Push(&receiver);
   5180       }
   5181 
   5182       // Call the function.
   5183       CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
   5184     }
   5185 
   5186   } else {
   5187     // ----------------------------------
   5188     // JavaScript example: 'foo(1, 2, 3)'  // foo is not global
   5189     // ----------------------------------
   5190 
   5191     // Load the function.
   5192     Load(function);
   5193 
   5194     // Pass the global proxy as the receiver.
   5195     LoadGlobalReceiver();
   5196 
   5197     // Call the function.
   5198     CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
   5199   }
   5200 }
   5201 
   5202 
   5203 void CodeGenerator::VisitCallNew(CallNew* node) {
   5204   Comment cmnt(masm_, "[ CallNew");
   5205 
   5206   // According to ECMA-262, section 11.2.2, page 44, the function
   5207   // expression in new calls must be evaluated before the
   5208   // arguments. This is different from ordinary calls, where the
   5209   // actual function to call is resolved after the arguments have been
   5210   // evaluated.
   5211 
   5212   // Compute function to call and use the global object as the
   5213   // receiver. There is no need to use the global proxy here because
   5214   // it will always be replaced with a newly allocated object.
   5215   Load(node->expression());
   5216   LoadGlobal();
   5217 
   5218   // Push the arguments ("left-to-right") on the stack.
   5219   ZoneList<Expression*>* args = node->arguments();
   5220   int arg_count = args->length();
   5221   for (int i = 0; i < arg_count; i++) {
   5222     Load(args->at(i));
   5223   }
   5224 
   5225   // Call the construct call builtin that handles allocation and
   5226   // constructor invocation.
   5227   CodeForSourcePosition(node->position());
   5228   Result result = frame_->CallConstructor(arg_count);
   5229   // Replace the function on the stack with the result.
   5230   frame_->SetElementAt(0, &result);
   5231 }
   5232 
   5233 
   5234 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
   5235   ASSERT(args->length() == 1);
   5236   Load(args->at(0));
   5237   Result value = frame_->Pop();
   5238   value.ToRegister();
   5239   ASSERT(value.is_valid());
   5240   __ test(value.reg(), Immediate(kSmiTagMask));
   5241   value.Unuse();
   5242   destination()->Split(zero);
   5243 }
   5244 
   5245 
   5246 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
   5247   // Conditionally generate a log call.
   5248   // Args:
   5249   //   0 (literal string): The type of logging (corresponds to the flags).
   5250   //     This is used to determine whether or not to generate the log call.
   5251   //   1 (string): Format string.  Access the string at argument index 2
   5252   //     with '%2s' (see Logger::LogRuntime for all the formats).
   5253   //   2 (array): Arguments to the format string.
   5254   ASSERT_EQ(args->length(), 3);
   5255 #ifdef ENABLE_LOGGING_AND_PROFILING
   5256   if (ShouldGenerateLog(args->at(0))) {
   5257     Load(args->at(1));
   5258     Load(args->at(2));
   5259     frame_->CallRuntime(Runtime::kLog, 2);
   5260   }
   5261 #endif
   5262   // Finally, we're expected to leave a value on the top of the stack.
   5263   frame_->Push(Factory::undefined_value());
   5264 }
   5265 
   5266 
   5267 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
   5268   ASSERT(args->length() == 1);
   5269   Load(args->at(0));
   5270   Result value = frame_->Pop();
   5271   value.ToRegister();
   5272   ASSERT(value.is_valid());
   5273   __ test(value.reg(), Immediate(kSmiTagMask | 0x80000000));
   5274   value.Unuse();
   5275   destination()->Split(zero);
   5276 }
   5277 
   5278 
   5279 // This generates code that performs a charCodeAt() call or returns
   5280 // undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
   5281 // It can handle flat, 8 and 16 bit characters and cons strings where the
   5282 // answer is found in the left hand branch of the cons.  The slow case will
   5283 // flatten the string, which will ensure that the answer is in the left hand
   5284 // side the next time around.
   5285 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
   5286   Comment(masm_, "[ GenerateFastCharCodeAt");
   5287   ASSERT(args->length() == 2);
   5288 
   5289   Label slow_case;
   5290   Label end;
   5291   Label not_a_flat_string;
   5292   Label try_again_with_new_string;
   5293   Label ascii_string;
   5294   Label got_char_code;
   5295 
   5296   Load(args->at(0));
   5297   Load(args->at(1));
   5298   Result index = frame_->Pop();
   5299   Result object = frame_->Pop();
   5300 
   5301   // Get register ecx to use as shift amount later.
   5302   Result shift_amount;
   5303   if (object.is_register() && object.reg().is(ecx)) {
   5304     Result fresh = allocator_->Allocate();
   5305     shift_amount = object;
   5306     object = fresh;
   5307     __ mov(object.reg(), ecx);
   5308   }
   5309   if (index.is_register() && index.reg().is(ecx)) {
   5310     Result fresh = allocator_->Allocate();
   5311     shift_amount = index;
   5312     index = fresh;
   5313     __ mov(index.reg(), ecx);
   5314   }
   5315   // There could be references to ecx in the frame. Allocating will
   5316   // spill them, otherwise spill explicitly.
   5317   if (shift_amount.is_valid()) {
   5318     frame_->Spill(ecx);
   5319   } else {
   5320     shift_amount = allocator()->Allocate(ecx);
   5321   }
   5322   ASSERT(shift_amount.is_register());
   5323   ASSERT(shift_amount.reg().is(ecx));
   5324   ASSERT(allocator_->count(ecx) == 1);
   5325 
   5326   // We will mutate the index register and possibly the object register.
   5327   // The case where they are somehow the same register is handled
   5328   // because we only mutate them in the case where the receiver is a
   5329   // heap object and the index is not.
   5330   object.ToRegister();
   5331   index.ToRegister();
   5332   frame_->Spill(object.reg());
   5333   frame_->Spill(index.reg());
   5334 
   5335   // We need a single extra temporary register.
   5336   Result temp = allocator()->Allocate();
   5337   ASSERT(temp.is_valid());
   5338 
   5339   // There is no virtual frame effect from here up to the final result
   5340   // push.
   5341 
   5342   // If the receiver is a smi trigger the slow case.
   5343   ASSERT(kSmiTag == 0);
   5344   __ test(object.reg(), Immediate(kSmiTagMask));
   5345   __ j(zero, &slow_case);
   5346 
   5347   // If the index is negative or non-smi trigger the slow case.
   5348   ASSERT(kSmiTag == 0);
   5349   __ test(index.reg(), Immediate(kSmiTagMask | 0x80000000));
   5350   __ j(not_zero, &slow_case);
   5351   // Untag the index.
   5352   __ SmiUntag(index.reg());
   5353 
   5354   __ bind(&try_again_with_new_string);
   5355   // Fetch the instance type of the receiver into ecx.
   5356   __ mov(ecx, FieldOperand(object.reg(), HeapObject::kMapOffset));
   5357   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   5358   // If the receiver is not a string trigger the slow case.
   5359   __ test(ecx, Immediate(kIsNotStringMask));
   5360   __ j(not_zero, &slow_case);
   5361 
   5362   // Fetch the length field into the temporary register.
   5363   __ mov(temp.reg(), FieldOperand(object.reg(), String::kLengthOffset));
   5364   // Check for index out of range.
   5365   __ cmp(index.reg(), Operand(temp.reg()));
   5366   __ j(greater_equal, &slow_case);
   5367   // Reload the instance type (into the temp register this time)..
   5368   __ mov(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
   5369   __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
   5370 
   5371   // We need special handling for non-flat strings.
   5372   ASSERT(kSeqStringTag == 0);
   5373   __ test(temp.reg(), Immediate(kStringRepresentationMask));
   5374   __ j(not_zero, &not_a_flat_string);
   5375   // Check for 1-byte or 2-byte string.
   5376   __ test(temp.reg(), Immediate(kStringEncodingMask));
   5377   __ j(not_zero, &ascii_string);
   5378 
   5379   // 2-byte string.
   5380   // Load the 2-byte character code into the temp register.
   5381   __ movzx_w(temp.reg(), FieldOperand(object.reg(),
   5382                                       index.reg(),
   5383                                       times_2,
   5384                                       SeqTwoByteString::kHeaderSize));
   5385   __ jmp(&got_char_code);
   5386 
   5387   // ASCII string.
   5388   __ bind(&ascii_string);
   5389   // Load the byte into the temp register.
   5390   __ movzx_b(temp.reg(), FieldOperand(object.reg(),
   5391                                       index.reg(),
   5392                                       times_1,
   5393                                       SeqAsciiString::kHeaderSize));
   5394   __ bind(&got_char_code);
   5395   __ SmiTag(temp.reg());
   5396   __ jmp(&end);
   5397 
   5398   // Handle non-flat strings.
   5399   __ bind(&not_a_flat_string);
   5400   __ and_(temp.reg(), kStringRepresentationMask);
   5401   __ cmp(temp.reg(), kConsStringTag);
   5402   __ j(not_equal, &slow_case);
   5403 
   5404   // ConsString.
   5405   // Check that the right hand side is the empty string (ie if this is really a
   5406   // flat string in a cons string).  If that is not the case we would rather go
   5407   // to the runtime system now, to flatten the string.
   5408   __ mov(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset));
   5409   __ cmp(Operand(temp.reg()), Factory::empty_string());
   5410   __ j(not_equal, &slow_case);
   5411   // Get the first of the two strings.
   5412   __ mov(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
   5413   __ jmp(&try_again_with_new_string);
   5414 
   5415   __ bind(&slow_case);
   5416   // Move the undefined value into the result register, which will
   5417   // trigger the slow case.
   5418   __ Set(temp.reg(), Immediate(Factory::undefined_value()));
   5419 
   5420   __ bind(&end);
   5421   frame_->Push(&temp);
   5422 }
   5423 
   5424 
   5425 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
   5426   ASSERT(args->length() == 1);
   5427   Load(args->at(0));
   5428   Result value = frame_->Pop();
   5429   value.ToRegister();
   5430   ASSERT(value.is_valid());
   5431   __ test(value.reg(), Immediate(kSmiTagMask));
   5432   destination()->false_target()->Branch(equal);
   5433   // It is a heap object - get map.
   5434   Result temp = allocator()->Allocate();
   5435   ASSERT(temp.is_valid());
   5436   // Check if the object is a JS array or not.
   5437   __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, temp.reg());
   5438   value.Unuse();
   5439   temp.Unuse();
   5440   destination()->Split(equal);
   5441 }
   5442 
   5443 
   5444 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
   5445   ASSERT(args->length() == 1);
   5446   Load(args->at(0));
   5447   Result value = frame_->Pop();
   5448   value.ToRegister();
   5449   ASSERT(value.is_valid());
   5450   __ test(value.reg(), Immediate(kSmiTagMask));
   5451   destination()->false_target()->Branch(equal);
   5452   // It is a heap object - get map.
   5453   Result temp = allocator()->Allocate();
   5454   ASSERT(temp.is_valid());
   5455   // Check if the object is a regexp.
   5456   __ CmpObjectType(value.reg(), JS_REGEXP_TYPE, temp.reg());
   5457   value.Unuse();
   5458   temp.Unuse();
   5459   destination()->Split(equal);
   5460 }
   5461 
   5462 
   5463 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
   5464   // This generates a fast version of:
   5465   // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
   5466   ASSERT(args->length() == 1);
   5467   Load(args->at(0));
   5468   Result obj = frame_->Pop();
   5469   obj.ToRegister();
   5470 
   5471   __ test(obj.reg(), Immediate(kSmiTagMask));
   5472   destination()->false_target()->Branch(zero);
   5473   __ cmp(obj.reg(), Factory::null_value());
   5474   destination()->true_target()->Branch(equal);
   5475 
   5476   Result map = allocator()->Allocate();
   5477   ASSERT(map.is_valid());
   5478   __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
   5479   // Undetectable objects behave like undefined when tested with typeof.
   5480   __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset));
   5481   __ test(map.reg(), Immediate(1 << Map::kIsUndetectable));
   5482   destination()->false_target()->Branch(not_zero);
   5483   __ mov(map.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
   5484   __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset));
   5485   __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE);
   5486   destination()->false_target()->Branch(less);
   5487   __ cmp(map.reg(), LAST_JS_OBJECT_TYPE);
   5488   obj.Unuse();
   5489   map.Unuse();
   5490   destination()->Split(less_equal);
   5491 }
   5492 
   5493 
   5494 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
   5495   // This generates a fast version of:
   5496   // (%_ClassOf(arg) === 'Function')
   5497   ASSERT(args->length() == 1);
   5498   Load(args->at(0));
   5499   Result obj = frame_->Pop();
   5500   obj.ToRegister();
   5501   __ test(obj.reg(), Immediate(kSmiTagMask));
   5502   destination()->false_target()->Branch(zero);
   5503   Result temp = allocator()->Allocate();
   5504   ASSERT(temp.is_valid());
   5505   __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, temp.reg());
   5506   obj.Unuse();
   5507   temp.Unuse();
   5508   destination()->Split(equal);
   5509 }
   5510 
   5511 
   5512 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
   5513   ASSERT(args->length() == 1);
   5514   Load(args->at(0));
   5515   Result obj = frame_->Pop();
   5516   obj.ToRegister();
   5517   __ test(obj.reg(), Immediate(kSmiTagMask));
   5518   destination()->false_target()->Branch(zero);
   5519   Result temp = allocator()->Allocate();
   5520   ASSERT(temp.is_valid());
   5521   __ mov(temp.reg(),
   5522          FieldOperand(obj.reg(), HeapObject::kMapOffset));
   5523   __ movzx_b(temp.reg(),
   5524              FieldOperand(temp.reg(), Map::kBitFieldOffset));
   5525   __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
   5526   obj.Unuse();
   5527   temp.Unuse();
   5528   destination()->Split(not_zero);
   5529 }
   5530 
   5531 
   5532 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
   5533   ASSERT(args->length() == 0);
   5534 
   5535   // Get the frame pointer for the calling frame.
   5536   Result fp = allocator()->Allocate();
   5537   __ mov(fp.reg(), Operand(ebp, StandardFrameConstants::kCallerFPOffset));
   5538 
   5539   // Skip the arguments adaptor frame if it exists.
   5540   Label check_frame_marker;
   5541   __ cmp(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
   5542          Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   5543   __ j(not_equal, &check_frame_marker);
   5544   __ mov(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset));
   5545 
   5546   // Check the marker in the calling frame.
   5547   __ bind(&check_frame_marker);
   5548   __ cmp(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
   5549          Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
   5550   fp.Unuse();
   5551   destination()->Split(equal);
   5552 }
   5553 
   5554 
   5555 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
   5556   ASSERT(args->length() == 0);
   5557   // ArgumentsAccessStub takes the parameter count as an input argument
   5558   // in register eax.  Create a constant result for it.
   5559   Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters())));
   5560   // Call the shared stub to get to the arguments.length.
   5561   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
   5562   Result result = frame_->CallStub(&stub, &count);
   5563   frame_->Push(&result);
   5564 }
   5565 
   5566 
   5567 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
   5568   ASSERT(args->length() == 1);
   5569   JumpTarget leave, null, function, non_function_constructor;
   5570   Load(args->at(0));  // Load the object.
   5571   Result obj = frame_->Pop();
   5572   obj.ToRegister();
   5573   frame_->Spill(obj.reg());
   5574 
   5575   // If the object is a smi, we return null.
   5576   __ test(obj.reg(), Immediate(kSmiTagMask));
   5577   null.Branch(zero);
   5578 
   5579   // Check that the object is a JS object but take special care of JS
   5580   // functions to make sure they have 'Function' as their class.
   5581   { Result tmp = allocator()->Allocate();
   5582     __ mov(obj.reg(), FieldOperand(obj.reg(), HeapObject::kMapOffset));
   5583     __ movzx_b(tmp.reg(), FieldOperand(obj.reg(), Map::kInstanceTypeOffset));
   5584     __ cmp(tmp.reg(), FIRST_JS_OBJECT_TYPE);
   5585     null.Branch(less);
   5586 
   5587     // As long as JS_FUNCTION_TYPE is the last instance type and it is
   5588     // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
   5589     // LAST_JS_OBJECT_TYPE.
   5590     ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
   5591     ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
   5592     __ cmp(tmp.reg(), JS_FUNCTION_TYPE);
   5593     function.Branch(equal);
   5594   }
   5595 
   5596   // Check if the constructor in the map is a function.
   5597   { Result tmp = allocator()->Allocate();
   5598     __ mov(obj.reg(), FieldOperand(obj.reg(), Map::kConstructorOffset));
   5599     __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, tmp.reg());
   5600     non_function_constructor.Branch(not_equal);
   5601   }
   5602 
   5603   // The map register now contains the constructor function. Grab the
   5604   // instance class name from there.
   5605   __ mov(obj.reg(),
   5606          FieldOperand(obj.reg(), JSFunction::kSharedFunctionInfoOffset));
   5607   __ mov(obj.reg(),
   5608          FieldOperand(obj.reg(), SharedFunctionInfo::kInstanceClassNameOffset));
   5609   frame_->Push(&obj);
   5610   leave.Jump();
   5611 
   5612   // Functions have class 'Function'.
   5613   function.Bind();
   5614   frame_->Push(Factory::function_class_symbol());
   5615   leave.Jump();
   5616 
   5617   // Objects with a non-function constructor have class 'Object'.
   5618   non_function_constructor.Bind();
   5619   frame_->Push(Factory::Object_symbol());
   5620   leave.Jump();
   5621 
   5622   // Non-JS objects have class null.
   5623   null.Bind();
   5624   frame_->Push(Factory::null_value());
   5625 
   5626   // All done.
   5627   leave.Bind();
   5628 }
   5629 
   5630 
   5631 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
   5632   ASSERT(args->length() == 1);
   5633   JumpTarget leave;
   5634   Load(args->at(0));  // Load the object.
   5635   frame_->Dup();
   5636   Result object = frame_->Pop();
   5637   object.ToRegister();
   5638   ASSERT(object.is_valid());
   5639   // if (object->IsSmi()) return object.
   5640   __ test(object.reg(), Immediate(kSmiTagMask));
   5641   leave.Branch(zero, taken);
   5642   // It is a heap object - get map.
   5643   Result temp = allocator()->Allocate();
   5644   ASSERT(temp.is_valid());
   5645   // if (!object->IsJSValue()) return object.
   5646   __ CmpObjectType(object.reg(), JS_VALUE_TYPE, temp.reg());
   5647   leave.Branch(not_equal, not_taken);
   5648   __ mov(temp.reg(), FieldOperand(object.reg(), JSValue::kValueOffset));
   5649   object.Unuse();
   5650   frame_->SetElementAt(0, &temp);
   5651   leave.Bind();
   5652 }
   5653 
   5654 
   5655 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
   5656   ASSERT(args->length() == 2);
   5657   JumpTarget leave;
   5658   Load(args->at(0));  // Load the object.
   5659   Load(args->at(1));  // Load the value.
   5660   Result value = frame_->Pop();
   5661   Result object = frame_->Pop();
   5662   value.ToRegister();
   5663   object.ToRegister();
   5664 
   5665   // if (object->IsSmi()) return value.
   5666   __ test(object.reg(), Immediate(kSmiTagMask));
   5667   leave.Branch(zero, &value, taken);
   5668 
   5669   // It is a heap object - get its map.
   5670   Result scratch = allocator_->Allocate();
   5671   ASSERT(scratch.is_valid());
   5672   // if (!object->IsJSValue()) return value.
   5673   __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg());
   5674   leave.Branch(not_equal, &value, not_taken);
   5675 
   5676   // Store the value.
   5677   __ mov(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg());
   5678   // Update the write barrier.  Save the value as it will be
   5679   // overwritten by the write barrier code and is needed afterward.
   5680   Result duplicate_value = allocator_->Allocate();
   5681   ASSERT(duplicate_value.is_valid());
   5682   __ mov(duplicate_value.reg(), value.reg());
   5683   // The object register is also overwritten by the write barrier and
   5684   // possibly aliased in the frame.
   5685   frame_->Spill(object.reg());
   5686   __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(),
   5687                  scratch.reg());
   5688   object.Unuse();
   5689   scratch.Unuse();
   5690   duplicate_value.Unuse();
   5691 
   5692   // Leave.
   5693   leave.Bind(&value);
   5694   frame_->Push(&value);
   5695 }
   5696 
   5697 
   5698 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
   5699   ASSERT(args->length() == 1);
   5700 
   5701   // ArgumentsAccessStub expects the key in edx and the formal
   5702   // parameter count in eax.
   5703   Load(args->at(0));
   5704   Result key = frame_->Pop();
   5705   // Explicitly create a constant result.
   5706   Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters())));
   5707   // Call the shared stub to get to arguments[key].
   5708   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
   5709   Result result = frame_->CallStub(&stub, &key, &count);
   5710   frame_->Push(&result);
   5711 }
   5712 
   5713 
   5714 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
   5715   ASSERT(args->length() == 2);
   5716 
   5717   // Load the two objects into registers and perform the comparison.
   5718   Load(args->at(0));
   5719   Load(args->at(1));
   5720   Result right = frame_->Pop();
   5721   Result left = frame_->Pop();
   5722   right.ToRegister();
   5723   left.ToRegister();
   5724   __ cmp(right.reg(), Operand(left.reg()));
   5725   right.Unuse();
   5726   left.Unuse();
   5727   destination()->Split(equal);
   5728 }
   5729 
   5730 
   5731 void CodeGenerator::GenerateGetFramePointer(ZoneList<Expression*>* args) {
   5732   ASSERT(args->length() == 0);
   5733   ASSERT(kSmiTag == 0);  // EBP value is aligned, so it should look like Smi.
   5734   Result ebp_as_smi = allocator_->Allocate();
   5735   ASSERT(ebp_as_smi.is_valid());
   5736   __ mov(ebp_as_smi.reg(), Operand(ebp));
   5737   frame_->Push(&ebp_as_smi);
   5738 }
   5739 
   5740 
   5741 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
   5742   ASSERT(args->length() == 0);
   5743   frame_->SpillAll();
   5744 
   5745   // Make sure the frame is aligned like the OS expects.
   5746   static const int kFrameAlignment = OS::ActivationFrameAlignment();
   5747   if (kFrameAlignment > 0) {
   5748     ASSERT(IsPowerOf2(kFrameAlignment));
   5749     __ mov(edi, Operand(esp));  // Save in callee-saved register.
   5750     __ and_(esp, -kFrameAlignment);
   5751   }
   5752 
   5753   // Call V8::RandomPositiveSmi().
   5754   __ call(FUNCTION_ADDR(V8::RandomPositiveSmi), RelocInfo::RUNTIME_ENTRY);
   5755 
   5756   // Restore stack pointer from callee-saved register edi.
   5757   if (kFrameAlignment > 0) {
   5758     __ mov(esp, Operand(edi));
   5759   }
   5760 
   5761   Result result = allocator_->Allocate(eax);
   5762   frame_->Push(&result);
   5763 }
   5764 
   5765 
   5766 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
   5767   ASSERT_EQ(2, args->length());
   5768 
   5769   Load(args->at(0));
   5770   Load(args->at(1));
   5771 
   5772   StringAddStub stub(NO_STRING_ADD_FLAGS);
   5773   Result answer = frame_->CallStub(&stub, 2);
   5774   frame_->Push(&answer);
   5775 }
   5776 
   5777 
   5778 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
   5779   ASSERT_EQ(3, args->length());
   5780 
   5781   Load(args->at(0));
   5782   Load(args->at(1));
   5783   Load(args->at(2));
   5784 
   5785   SubStringStub stub;
   5786   Result answer = frame_->CallStub(&stub, 3);
   5787   frame_->Push(&answer);
   5788 }
   5789 
   5790 
   5791 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
   5792   ASSERT_EQ(2, args->length());
   5793 
   5794   Load(args->at(0));
   5795   Load(args->at(1));
   5796 
   5797   StringCompareStub stub;
   5798   Result answer = frame_->CallStub(&stub, 2);
   5799   frame_->Push(&answer);
   5800 }
   5801 
   5802 
   5803 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
   5804   ASSERT_EQ(args->length(), 4);
   5805 
   5806   // Load the arguments on the stack and call the stub.
   5807   Load(args->at(0));
   5808   Load(args->at(1));
   5809   Load(args->at(2));
   5810   Load(args->at(3));
   5811   RegExpExecStub stub;
   5812   Result result = frame_->CallStub(&stub, 4);
   5813   frame_->Push(&result);
   5814 }
   5815 
   5816 
   5817 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
   5818   ASSERT_EQ(args->length(), 1);
   5819 
   5820   // Load the argument on the stack and call the stub.
   5821   Load(args->at(0));
   5822   NumberToStringStub stub;
   5823   Result result = frame_->CallStub(&stub, 1);
   5824   frame_->Push(&result);
   5825 }
   5826 
   5827 
   5828 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
   5829   ASSERT_EQ(args->length(), 1);
   5830   Load(args->at(0));
   5831   TranscendentalCacheStub stub(TranscendentalCache::SIN);
   5832   Result result = frame_->CallStub(&stub, 1);
   5833   frame_->Push(&result);
   5834 }
   5835 
   5836 
   5837 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
   5838   ASSERT_EQ(args->length(), 1);
   5839   Load(args->at(0));
   5840   TranscendentalCacheStub stub(TranscendentalCache::COS);
   5841   Result result = frame_->CallStub(&stub, 1);
   5842   frame_->Push(&result);
   5843 }
   5844 
   5845 
   5846 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
   5847   if (CheckForInlineRuntimeCall(node)) {
   5848     return;
   5849   }
   5850 
   5851   ZoneList<Expression*>* args = node->arguments();
   5852   Comment cmnt(masm_, "[ CallRuntime");
   5853   Runtime::Function* function = node->function();
   5854 
   5855   if (function == NULL) {
   5856     // Push the builtins object found in the current global object.
   5857     Result temp = allocator()->Allocate();
   5858     ASSERT(temp.is_valid());
   5859     __ mov(temp.reg(), GlobalObject());
   5860     __ mov(temp.reg(), FieldOperand(temp.reg(), GlobalObject::kBuiltinsOffset));
   5861     frame_->Push(&temp);
   5862   }
   5863 
   5864   // Push the arguments ("left-to-right").
   5865   int arg_count = args->length();
   5866   for (int i = 0; i < arg_count; i++) {
   5867     Load(args->at(i));
   5868   }
   5869 
   5870   if (function == NULL) {
   5871     // Call the JS runtime function.
   5872     frame_->Push(node->name());
   5873     Result answer = frame_->CallCallIC(RelocInfo::CODE_TARGET,
   5874                                        arg_count,
   5875                                        loop_nesting_);
   5876     frame_->RestoreContextRegister();
   5877     frame_->Push(&answer);
   5878   } else {
   5879     // Call the C runtime function.
   5880     Result answer = frame_->CallRuntime(function, arg_count);
   5881     frame_->Push(&answer);
   5882   }
   5883 }
   5884 
   5885 
   5886 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
   5887   Comment cmnt(masm_, "[ UnaryOperation");
   5888 
   5889   Token::Value op = node->op();
   5890 
   5891   if (op == Token::NOT) {
   5892     // Swap the true and false targets but keep the same actual label
   5893     // as the fall through.
   5894     destination()->Invert();
   5895     LoadCondition(node->expression(), destination(), true);
   5896     // Swap the labels back.
   5897     destination()->Invert();
   5898 
   5899   } else if (op == Token::DELETE) {
   5900     Property* property = node->expression()->AsProperty();
   5901     if (property != NULL) {
   5902       Load(property->obj());
   5903       Load(property->key());
   5904       Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 2);
   5905       frame_->Push(&answer);
   5906       return;
   5907     }
   5908 
   5909     Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
   5910     if (variable != NULL) {
   5911       Slot* slot = variable->slot();
   5912       if (variable->is_global()) {
   5913         LoadGlobal();
   5914         frame_->Push(variable->name());
   5915         Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
   5916                                               CALL_FUNCTION, 2);
   5917         frame_->Push(&answer);
   5918         return;
   5919 
   5920       } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
   5921         // Call the runtime to look up the context holding the named
   5922         // variable.  Sync the virtual frame eagerly so we can push the
   5923         // arguments directly into place.
   5924         frame_->SyncRange(0, frame_->element_count() - 1);
   5925         frame_->EmitPush(esi);
   5926         frame_->EmitPush(Immediate(variable->name()));
   5927         Result context = frame_->CallRuntime(Runtime::kLookupContext, 2);
   5928         ASSERT(context.is_register());
   5929         frame_->EmitPush(context.reg());
   5930         context.Unuse();
   5931         frame_->EmitPush(Immediate(variable->name()));
   5932         Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
   5933                                               CALL_FUNCTION, 2);
   5934         frame_->Push(&answer);
   5935         return;
   5936       }
   5937 
   5938       // Default: Result of deleting non-global, not dynamically
   5939       // introduced variables is false.
   5940       frame_->Push(Factory::false_value());
   5941 
   5942     } else {
   5943       // Default: Result of deleting expressions is true.
   5944       Load(node->expression());  // may have side-effects
   5945       frame_->SetElementAt(0, Factory::true_value());
   5946     }
   5947 
   5948   } else if (op == Token::TYPEOF) {
   5949     // Special case for loading the typeof expression; see comment on
   5950     // LoadTypeofExpression().
   5951     LoadTypeofExpression(node->expression());
   5952     Result answer = frame_->CallRuntime(Runtime::kTypeof, 1);
   5953     frame_->Push(&answer);
   5954 
   5955   } else if (op == Token::VOID) {
   5956     Expression* expression = node->expression();
   5957     if (expression && expression->AsLiteral() && (
   5958         expression->AsLiteral()->IsTrue() ||
   5959         expression->AsLiteral()->IsFalse() ||
   5960         expression->AsLiteral()->handle()->IsNumber() ||
   5961         expression->AsLiteral()->handle()->IsString() ||
   5962         expression->AsLiteral()->handle()->IsJSRegExp() ||
   5963         expression->AsLiteral()->IsNull())) {
   5964       // Omit evaluating the value of the primitive literal.
   5965       // It will be discarded anyway, and can have no side effect.
   5966       frame_->Push(Factory::undefined_value());
   5967     } else {
   5968       Load(node->expression());
   5969       frame_->SetElementAt(0, Factory::undefined_value());
   5970     }
   5971 
   5972   } else {
   5973     Load(node->expression());
   5974     bool overwrite =
   5975         (node->expression()->AsBinaryOperation() != NULL &&
   5976          node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
   5977     switch (op) {
   5978       case Token::SUB: {
   5979         GenericUnaryOpStub stub(Token::SUB, overwrite);
   5980         Result operand = frame_->Pop();
   5981         Result answer = frame_->CallStub(&stub, &operand);
   5982         frame_->Push(&answer);
   5983         break;
   5984       }
   5985 
   5986       case Token::BIT_NOT: {
   5987         // Smi check.
   5988         JumpTarget smi_label;
   5989         JumpTarget continue_label;
   5990         Result operand = frame_->Pop();
   5991         operand.ToRegister();
   5992         __ test(operand.reg(), Immediate(kSmiTagMask));
   5993         smi_label.Branch(zero, &operand, taken);
   5994 
   5995         GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
   5996         Result answer = frame_->CallStub(&stub, &operand);
   5997         continue_label.Jump(&answer);
   5998 
   5999         smi_label.Bind(&answer);
   6000         answer.ToRegister();
   6001         frame_->Spill(answer.reg());
   6002         __ not_(answer.reg());
   6003         __ and_(answer.reg(), ~kSmiTagMask);  // Remove inverted smi-tag.
   6004 
   6005         continue_label.Bind(&answer);
   6006         frame_->Push(&answer);
   6007         break;
   6008       }
   6009 
   6010       case Token::ADD: {
   6011         // Smi check.
   6012         JumpTarget continue_label;
   6013         Result operand = frame_->Pop();
   6014         operand.ToRegister();
   6015         __ test(operand.reg(), Immediate(kSmiTagMask));
   6016         continue_label.Branch(zero, &operand, taken);
   6017 
   6018         frame_->Push(&operand);
   6019         Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER,
   6020                                               CALL_FUNCTION, 1);
   6021 
   6022         continue_label.Bind(&answer);
   6023         frame_->Push(&answer);
   6024         break;
   6025       }
   6026 
   6027       default:
   6028         // NOT, DELETE, TYPEOF, and VOID are handled outside the
   6029         // switch.
   6030         UNREACHABLE();
   6031     }
   6032   }
   6033 }
   6034 
   6035 
   6036 // The value in dst was optimistically incremented or decremented.  The
   6037 // result overflowed or was not smi tagged.  Undo the operation, call
   6038 // into the runtime to convert the argument to a number, and call the
   6039 // specialized add or subtract stub.  The result is left in dst.
   6040 class DeferredPrefixCountOperation: public DeferredCode {
   6041  public:
   6042   DeferredPrefixCountOperation(Register dst, bool is_increment)
   6043       : dst_(dst), is_increment_(is_increment) {
   6044     set_comment("[ DeferredCountOperation");
   6045   }
   6046 
   6047   virtual void Generate();
   6048 
   6049  private:
   6050   Register dst_;
   6051   bool is_increment_;
   6052 };
   6053 
   6054 
   6055 void DeferredPrefixCountOperation::Generate() {
   6056   // Undo the optimistic smi operation.
   6057   if (is_increment_) {
   6058     __ sub(Operand(dst_), Immediate(Smi::FromInt(1)));
   6059   } else {
   6060     __ add(Operand(dst_), Immediate(Smi::FromInt(1)));
   6061   }
   6062   __ push(dst_);
   6063   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
   6064   __ push(eax);
   6065   __ push(Immediate(Smi::FromInt(1)));
   6066   if (is_increment_) {
   6067     __ CallRuntime(Runtime::kNumberAdd, 2);
   6068   } else {
   6069     __ CallRuntime(Runtime::kNumberSub, 2);
   6070   }
   6071   if (!dst_.is(eax)) __ mov(dst_, eax);
   6072 }
   6073 
   6074 
   6075 // The value in dst was optimistically incremented or decremented.  The
   6076 // result overflowed or was not smi tagged.  Undo the operation and call
   6077 // into the runtime to convert the argument to a number.  Update the
   6078 // original value in old.  Call the specialized add or subtract stub.
   6079 // The result is left in dst.
   6080 class DeferredPostfixCountOperation: public DeferredCode {
   6081  public:
   6082   DeferredPostfixCountOperation(Register dst, Register old, bool is_increment)
   6083       : dst_(dst), old_(old), is_increment_(is_increment) {
   6084     set_comment("[ DeferredCountOperation");
   6085   }
   6086 
   6087   virtual void Generate();
   6088 
   6089  private:
   6090   Register dst_;
   6091   Register old_;
   6092   bool is_increment_;
   6093 };
   6094 
   6095 
   6096 void DeferredPostfixCountOperation::Generate() {
   6097   // Undo the optimistic smi operation.
   6098   if (is_increment_) {
   6099     __ sub(Operand(dst_), Immediate(Smi::FromInt(1)));
   6100   } else {
   6101     __ add(Operand(dst_), Immediate(Smi::FromInt(1)));
   6102   }
   6103   __ push(dst_);
   6104   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
   6105 
   6106   // Save the result of ToNumber to use as the old value.
   6107   __ push(eax);
   6108 
   6109   // Call the runtime for the addition or subtraction.
   6110   __ push(eax);
   6111   __ push(Immediate(Smi::FromInt(1)));
   6112   if (is_increment_) {
   6113     __ CallRuntime(Runtime::kNumberAdd, 2);
   6114   } else {
   6115     __ CallRuntime(Runtime::kNumberSub, 2);
   6116   }
   6117   if (!dst_.is(eax)) __ mov(dst_, eax);
   6118   __ pop(old_);
   6119 }
   6120 
   6121 
   6122 void CodeGenerator::VisitCountOperation(CountOperation* node) {
   6123   Comment cmnt(masm_, "[ CountOperation");
   6124 
   6125   bool is_postfix = node->is_postfix();
   6126   bool is_increment = node->op() == Token::INC;
   6127 
   6128   Variable* var = node->expression()->AsVariableProxy()->AsVariable();
   6129   bool is_const = (var != NULL && var->mode() == Variable::CONST);
   6130 
   6131   // Postfix operations need a stack slot under the reference to hold
   6132   // the old value while the new value is being stored.  This is so that
   6133   // in the case that storing the new value requires a call, the old
   6134   // value will be in the frame to be spilled.
   6135   if (is_postfix) frame_->Push(Smi::FromInt(0));
   6136 
   6137   // A constant reference is not saved to, so a constant reference is not a
   6138   // compound assignment reference.
   6139   { Reference target(this, node->expression(), !is_const);
   6140     if (target.is_illegal()) {
   6141       // Spoof the virtual frame to have the expected height (one higher
   6142       // than on entry).
   6143       if (!is_postfix) frame_->Push(Smi::FromInt(0));
   6144       return;
   6145     }
   6146     target.TakeValue();
   6147 
   6148     Result new_value = frame_->Pop();
   6149     new_value.ToRegister();
   6150 
   6151     Result old_value;  // Only allocated in the postfix case.
   6152     if (is_postfix) {
   6153       // Allocate a temporary to preserve the old value.
   6154       old_value = allocator_->Allocate();
   6155       ASSERT(old_value.is_valid());
   6156       __ mov(old_value.reg(), new_value.reg());
   6157     }
   6158     // Ensure the new value is writable.
   6159     frame_->Spill(new_value.reg());
   6160 
   6161     // In order to combine the overflow and the smi tag check, we need
   6162     // to be able to allocate a byte register.  We attempt to do so
   6163     // without spilling.  If we fail, we will generate separate overflow
   6164     // and smi tag checks.
   6165     //
   6166     // We allocate and clear the temporary byte register before
   6167     // performing the count operation since clearing the register using
   6168     // xor will clear the overflow flag.
   6169     Result tmp = allocator_->AllocateByteRegisterWithoutSpilling();
   6170     if (tmp.is_valid()) {
   6171       __ Set(tmp.reg(), Immediate(0));
   6172     }
   6173 
   6174     DeferredCode* deferred = NULL;
   6175     if (is_postfix) {
   6176       deferred = new DeferredPostfixCountOperation(new_value.reg(),
   6177                                                    old_value.reg(),
   6178                                                    is_increment);
   6179     } else {
   6180       deferred = new DeferredPrefixCountOperation(new_value.reg(),
   6181                                                   is_increment);
   6182     }
   6183 
   6184     if (is_increment) {
   6185       __ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
   6186     } else {
   6187       __ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
   6188     }
   6189 
   6190     // If the count operation didn't overflow and the result is a valid
   6191     // smi, we're done. Otherwise, we jump to the deferred slow-case
   6192     // code.
   6193     if (tmp.is_valid()) {
   6194       // We combine the overflow and the smi tag check if we could
   6195       // successfully allocate a temporary byte register.
   6196       __ setcc(overflow, tmp.reg());
   6197       __ or_(Operand(tmp.reg()), new_value.reg());
   6198       __ test(tmp.reg(), Immediate(kSmiTagMask));
   6199       tmp.Unuse();
   6200       deferred->Branch(not_zero);
   6201     } else {
   6202       // Otherwise we test separately for overflow and smi tag.
   6203       deferred->Branch(overflow);
   6204       __ test(new_value.reg(), Immediate(kSmiTagMask));
   6205       deferred->Branch(not_zero);
   6206     }
   6207     deferred->BindExit();
   6208 
   6209     // Postfix: store the old value in the allocated slot under the
   6210     // reference.
   6211     if (is_postfix) frame_->SetElementAt(target.size(), &old_value);
   6212 
   6213     frame_->Push(&new_value);
   6214     // Non-constant: update the reference.
   6215     if (!is_const) target.SetValue(NOT_CONST_INIT);
   6216   }
   6217 
   6218   // Postfix: drop the new value and use the old.
   6219   if (is_postfix) frame_->Drop();
   6220 }
   6221 
   6222 
   6223 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
   6224   Comment cmnt(masm_, "[ BinaryOperation");
   6225   Token::Value op = node->op();
   6226 
   6227   // According to ECMA-262 section 11.11, page 58, the binary logical
   6228   // operators must yield the result of one of the two expressions
   6229   // before any ToBoolean() conversions. This means that the value
   6230   // produced by a && or || operator is not necessarily a boolean.
   6231 
   6232   // NOTE: If the left hand side produces a materialized value (not
   6233   // control flow), we force the right hand side to do the same. This
   6234   // is necessary because we assume that if we get control flow on the
   6235   // last path out of an expression we got it on all paths.
   6236   if (op == Token::AND) {
   6237     JumpTarget is_true;
   6238     ControlDestination dest(&is_true, destination()->false_target(), true);
   6239     LoadCondition(node->left(), &dest, false);
   6240 
   6241     if (dest.false_was_fall_through()) {
   6242       // The current false target was used as the fall-through.  If
   6243       // there are no dangling jumps to is_true then the left
   6244       // subexpression was unconditionally false.  Otherwise we have
   6245       // paths where we do have to evaluate the right subexpression.
   6246       if (is_true.is_linked()) {
   6247         // We need to compile the right subexpression.  If the jump to
   6248         // the current false target was a forward jump then we have a
   6249         // valid frame, we have just bound the false target, and we
   6250         // have to jump around the code for the right subexpression.
   6251         if (has_valid_frame()) {
   6252           destination()->false_target()->Unuse();
   6253           destination()->false_target()->Jump();
   6254         }
   6255         is_true.Bind();
   6256         // The left subexpression compiled to control flow, so the
   6257         // right one is free to do so as well.
   6258         LoadCondition(node->right(), destination(), false);
   6259       } else {
   6260         // We have actually just jumped to or bound the current false
   6261         // target but the current control destination is not marked as
   6262         // used.
   6263         destination()->Use(false);
   6264       }
   6265 
   6266     } else if (dest.is_used()) {
   6267       // The left subexpression compiled to control flow (and is_true
   6268       // was just bound), so the right is free to do so as well.
   6269       LoadCondition(node->right(), destination(), false);
   6270 
   6271     } else {
   6272       // We have a materialized value on the frame, so we exit with
   6273       // one on all paths.  There are possibly also jumps to is_true
   6274       // from nested subexpressions.
   6275       JumpTarget pop_and_continue;
   6276       JumpTarget exit;
   6277 
   6278       // Avoid popping the result if it converts to 'false' using the
   6279       // standard ToBoolean() conversion as described in ECMA-262,
   6280       // section 9.2, page 30.
   6281       //
   6282       // Duplicate the TOS value. The duplicate will be popped by
   6283       // ToBoolean.
   6284       frame_->Dup();
   6285       ControlDestination dest(&pop_and_continue, &exit, true);
   6286       ToBoolean(&dest);
   6287 
   6288       // Pop the result of evaluating the first part.
   6289       frame_->Drop();
   6290 
   6291       // Compile right side expression.
   6292       is_true.Bind();
   6293       Load(node->right());
   6294 
   6295       // Exit (always with a materialized value).
   6296       exit.Bind();
   6297     }
   6298 
   6299   } else if (op == Token::OR) {
   6300     JumpTarget is_false;
   6301     ControlDestination dest(destination()->true_target(), &is_false, false);
   6302     LoadCondition(node->left(), &dest, false);
   6303 
   6304     if (dest.true_was_fall_through()) {
   6305       // The current true target was used as the fall-through.  If
   6306       // there are no dangling jumps to is_false then the left
   6307       // subexpression was unconditionally true.  Otherwise we have
   6308       // paths where we do have to evaluate the right subexpression.
   6309       if (is_false.is_linked()) {
   6310         // We need to compile the right subexpression.  If the jump to
   6311         // the current true target was a forward jump then we have a
   6312         // valid frame, we have just bound the true target, and we
   6313         // have to jump around the code for the right subexpression.
   6314         if (has_valid_frame()) {
   6315           destination()->true_target()->Unuse();
   6316           destination()->true_target()->Jump();
   6317         }
   6318         is_false.Bind();
   6319         // The left subexpression compiled to control flow, so the
   6320         // right one is free to do so as well.
   6321         LoadCondition(node->right(), destination(), false);
   6322       } else {
   6323         // We have just jumped to or bound the current true target but
   6324         // the current control destination is not marked as used.
   6325         destination()->Use(true);
   6326       }
   6327 
   6328     } else if (dest.is_used()) {
   6329       // The left subexpression compiled to control flow (and is_false
   6330       // was just bound), so the right is free to do so as well.
   6331       LoadCondition(node->right(), destination(), false);
   6332 
   6333     } else {
   6334       // We have a materialized value on the frame, so we exit with
   6335       // one on all paths.  There are possibly also jumps to is_false
   6336       // from nested subexpressions.
   6337       JumpTarget pop_and_continue;
   6338       JumpTarget exit;
   6339 
   6340       // Avoid popping the result if it converts to 'true' using the
   6341       // standard ToBoolean() conversion as described in ECMA-262,
   6342       // section 9.2, page 30.
   6343       //
   6344       // Duplicate the TOS value. The duplicate will be popped by
   6345       // ToBoolean.
   6346       frame_->Dup();
   6347       ControlDestination dest(&exit, &pop_and_continue, false);
   6348       ToBoolean(&dest);
   6349 
   6350       // Pop the result of evaluating the first part.
   6351       frame_->Drop();
   6352 
   6353       // Compile right side expression.
   6354       is_false.Bind();
   6355       Load(node->right());
   6356 
   6357       // Exit (always with a materialized value).
   6358       exit.Bind();
   6359     }
   6360 
   6361   } else {
   6362     // NOTE: The code below assumes that the slow cases (calls to runtime)
   6363     // never return a constant/immutable object.
   6364     OverwriteMode overwrite_mode = NO_OVERWRITE;
   6365     if (node->left()->AsBinaryOperation() != NULL &&
   6366         node->left()->AsBinaryOperation()->ResultOverwriteAllowed()) {
   6367       overwrite_mode = OVERWRITE_LEFT;
   6368     } else if (node->right()->AsBinaryOperation() != NULL &&
   6369                node->right()->AsBinaryOperation()->ResultOverwriteAllowed()) {
   6370       overwrite_mode = OVERWRITE_RIGHT;
   6371     }
   6372 
   6373     Load(node->left());
   6374     Load(node->right());
   6375     GenericBinaryOperation(node->op(), node->type(), overwrite_mode);
   6376   }
   6377 }
   6378 
   6379 
   6380 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
   6381   frame_->PushFunction();
   6382 }
   6383 
   6384 
   6385 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
   6386   Comment cmnt(masm_, "[ CompareOperation");
   6387 
   6388   bool left_already_loaded = false;
   6389 
   6390   // Get the expressions from the node.
   6391   Expression* left = node->left();
   6392   Expression* right = node->right();
   6393   Token::Value op = node->op();
   6394   // To make typeof testing for natives implemented in JavaScript really
   6395   // efficient, we generate special code for expressions of the form:
   6396   // 'typeof <expression> == <string>'.
   6397   UnaryOperation* operation = left->AsUnaryOperation();
   6398   if ((op == Token::EQ || op == Token::EQ_STRICT) &&
   6399       (operation != NULL && operation->op() == Token::TYPEOF) &&
   6400       (right->AsLiteral() != NULL &&
   6401        right->AsLiteral()->handle()->IsString())) {
   6402     Handle<String> check(String::cast(*right->AsLiteral()->handle()));
   6403 
   6404     // Load the operand and move it to a register.
   6405     LoadTypeofExpression(operation->expression());
   6406     Result answer = frame_->Pop();
   6407     answer.ToRegister();
   6408 
   6409     if (check->Equals(Heap::number_symbol())) {
   6410       __ test(answer.reg(), Immediate(kSmiTagMask));
   6411       destination()->true_target()->Branch(zero);
   6412       frame_->Spill(answer.reg());
   6413       __ mov(answer.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
   6414       __ cmp(answer.reg(), Factory::heap_number_map());
   6415       answer.Unuse();
   6416       destination()->Split(equal);
   6417 
   6418     } else if (check->Equals(Heap::string_symbol())) {
   6419       __ test(answer.reg(), Immediate(kSmiTagMask));
   6420       destination()->false_target()->Branch(zero);
   6421 
   6422       // It can be an undetectable string object.
   6423       Result temp = allocator()->Allocate();
   6424       ASSERT(temp.is_valid());
   6425       __ mov(temp.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
   6426       __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kBitFieldOffset));
   6427       __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
   6428       destination()->false_target()->Branch(not_zero);
   6429       __ CmpObjectType(answer.reg(), FIRST_NONSTRING_TYPE, temp.reg());
   6430       temp.Unuse();
   6431       answer.Unuse();
   6432       destination()->Split(below);
   6433 
   6434     } else if (check->Equals(Heap::boolean_symbol())) {
   6435       __ cmp(answer.reg(), Factory::true_value());
   6436       destination()->true_target()->Branch(equal);
   6437       __ cmp(answer.reg(), Factory::false_value());
   6438       answer.Unuse();
   6439       destination()->Split(equal);
   6440 
   6441     } else if (check->Equals(Heap::undefined_symbol())) {
   6442       __ cmp(answer.reg(), Factory::undefined_value());
   6443       destination()->true_target()->Branch(equal);
   6444 
   6445       __ test(answer.reg(), Immediate(kSmiTagMask));
   6446       destination()->false_target()->Branch(zero);
   6447 
   6448       // It can be an undetectable object.
   6449       frame_->Spill(answer.reg());
   6450       __ mov(answer.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
   6451       __ movzx_b(answer.reg(),
   6452                  FieldOperand(answer.reg(), Map::kBitFieldOffset));
   6453       __ test(answer.reg(), Immediate(1 << Map::kIsUndetectable));
   6454       answer.Unuse();
   6455       destination()->Split(not_zero);
   6456 
   6457     } else if (check->Equals(Heap::function_symbol())) {
   6458       __ test(answer.reg(), Immediate(kSmiTagMask));
   6459       destination()->false_target()->Branch(zero);
   6460       frame_->Spill(answer.reg());
   6461       __ CmpObjectType(answer.reg(), JS_FUNCTION_TYPE, answer.reg());
   6462       destination()->true_target()->Branch(equal);
   6463       // Regular expressions are callable so typeof == 'function'.
   6464       __ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE);
   6465       answer.Unuse();
   6466       destination()->Split(equal);
   6467     } else if (check->Equals(Heap::object_symbol())) {
   6468       __ test(answer.reg(), Immediate(kSmiTagMask));
   6469       destination()->false_target()->Branch(zero);
   6470       __ cmp(answer.reg(), Factory::null_value());
   6471       destination()->true_target()->Branch(equal);
   6472 
   6473       Result map = allocator()->Allocate();
   6474       ASSERT(map.is_valid());
   6475       // Regular expressions are typeof == 'function', not 'object'.
   6476       __ CmpObjectType(answer.reg(), JS_REGEXP_TYPE, map.reg());
   6477       destination()->false_target()->Branch(equal);
   6478 
   6479       // It can be an undetectable object.
   6480       __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kBitFieldOffset));
   6481       __ test(map.reg(), Immediate(1 << Map::kIsUndetectable));
   6482       destination()->false_target()->Branch(not_zero);
   6483       __ mov(map.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
   6484       __ movzx_b(map.reg(), FieldOperand(map.reg(), Map::kInstanceTypeOffset));
   6485       __ cmp(map.reg(), FIRST_JS_OBJECT_TYPE);
   6486       destination()->false_target()->Branch(less);
   6487       __ cmp(map.reg(), LAST_JS_OBJECT_TYPE);
   6488       answer.Unuse();
   6489       map.Unuse();
   6490       destination()->Split(less_equal);
   6491     } else {
   6492       // Uncommon case: typeof testing against a string literal that is
   6493       // never returned from the typeof operator.
   6494       answer.Unuse();
   6495       destination()->Goto(false);
   6496     }
   6497     return;
   6498   } else if (op == Token::LT &&
   6499              right->AsLiteral() != NULL &&
   6500              right->AsLiteral()->handle()->IsHeapNumber()) {
   6501     Handle<HeapNumber> check(HeapNumber::cast(*right->AsLiteral()->handle()));
   6502     if (check->value() == 2147483648.0) {  // 0x80000000.
   6503       Load(left);
   6504       left_already_loaded = true;
   6505       Result lhs = frame_->Pop();
   6506       lhs.ToRegister();
   6507       __ test(lhs.reg(), Immediate(kSmiTagMask));
   6508       destination()->true_target()->Branch(zero);  // All Smis are less.
   6509       Result scratch = allocator()->Allocate();
   6510       ASSERT(scratch.is_valid());
   6511       __ mov(scratch.reg(), FieldOperand(lhs.reg(), HeapObject::kMapOffset));
   6512       __ cmp(scratch.reg(), Factory::heap_number_map());
   6513       JumpTarget not_a_number;
   6514       not_a_number.Branch(not_equal, &lhs);
   6515       __ mov(scratch.reg(),
   6516              FieldOperand(lhs.reg(), HeapNumber::kExponentOffset));
   6517       __ cmp(Operand(scratch.reg()), Immediate(0xfff00000));
   6518       not_a_number.Branch(above_equal, &lhs);  // It's a negative NaN or -Inf.
   6519       const uint32_t borderline_exponent =
   6520           (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift;
   6521       __ cmp(Operand(scratch.reg()), Immediate(borderline_exponent));
   6522       scratch.Unuse();
   6523       lhs.Unuse();
   6524       destination()->true_target()->Branch(less);
   6525       destination()->false_target()->Jump();
   6526 
   6527       not_a_number.Bind(&lhs);
   6528       frame_->Push(&lhs);
   6529     }
   6530   }
   6531 
   6532   Condition cc = no_condition;
   6533   bool strict = false;
   6534   switch (op) {
   6535     case Token::EQ_STRICT:
   6536       strict = true;
   6537       // Fall through
   6538     case Token::EQ:
   6539       cc = equal;
   6540       break;
   6541     case Token::LT:
   6542       cc = less;
   6543       break;
   6544     case Token::GT:
   6545       cc = greater;
   6546       break;
   6547     case Token::LTE:
   6548       cc = less_equal;
   6549       break;
   6550     case Token::GTE:
   6551       cc = greater_equal;
   6552       break;
   6553     case Token::IN: {
   6554       if (!left_already_loaded) Load(left);
   6555       Load(right);
   6556       Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
   6557       frame_->Push(&answer);  // push the result
   6558       return;
   6559     }
   6560     case Token::INSTANCEOF: {
   6561       if (!left_already_loaded) Load(left);
   6562       Load(right);
   6563       InstanceofStub stub;
   6564       Result answer = frame_->CallStub(&stub, 2);
   6565       answer.ToRegister();
   6566       __ test(answer.reg(), Operand(answer.reg()));
   6567       answer.Unuse();
   6568       destination()->Split(zero);
   6569       return;
   6570     }
   6571     default:
   6572       UNREACHABLE();
   6573   }
   6574   if (!left_already_loaded) Load(left);
   6575   Load(right);
   6576   Comparison(node, cc, strict, destination());
   6577 }
   6578 
   6579 
   6580 #ifdef DEBUG
   6581 bool CodeGenerator::HasValidEntryRegisters() {
   6582   return (allocator()->count(eax) == (frame()->is_used(eax) ? 1 : 0))
   6583       && (allocator()->count(ebx) == (frame()->is_used(ebx) ? 1 : 0))
   6584       && (allocator()->count(ecx) == (frame()->is_used(ecx) ? 1 : 0))
   6585       && (allocator()->count(edx) == (frame()->is_used(edx) ? 1 : 0))
   6586       && (allocator()->count(edi) == (frame()->is_used(edi) ? 1 : 0));
   6587 }
   6588 #endif
   6589 
   6590 
   6591 // Emit a LoadIC call to get the value from receiver and leave it in
   6592 // dst.
   6593 class DeferredReferenceGetNamedValue: public DeferredCode {
   6594  public:
   6595   DeferredReferenceGetNamedValue(Register dst,
   6596                                  Register receiver,
   6597                                  Handle<String> name)
   6598       : dst_(dst), receiver_(receiver),  name_(name) {
   6599     set_comment("[ DeferredReferenceGetNamedValue");
   6600   }
   6601 
   6602   virtual void Generate();
   6603 
   6604   Label* patch_site() { return &patch_site_; }
   6605 
   6606  private:
   6607   Label patch_site_;
   6608   Register dst_;
   6609   Register receiver_;
   6610   Handle<String> name_;
   6611 };
   6612 
   6613 
   6614 void DeferredReferenceGetNamedValue::Generate() {
   6615   if (!receiver_.is(eax)) {
   6616     __ mov(eax, receiver_);
   6617   }
   6618   __ Set(ecx, Immediate(name_));
   6619   Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
   6620   __ call(ic, RelocInfo::CODE_TARGET);
   6621   // The call must be followed by a test eax instruction to indicate
   6622   // that the inobject property case was inlined.
   6623   //
   6624   // Store the delta to the map check instruction here in the test
   6625   // instruction.  Use masm_-> instead of the __ macro since the
   6626   // latter can't return a value.
   6627   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
   6628   // Here we use masm_-> instead of the __ macro because this is the
   6629   // instruction that gets patched and coverage code gets in the way.
   6630   masm_->test(eax, Immediate(-delta_to_patch_site));
   6631   __ IncrementCounter(&Counters::named_load_inline_miss, 1);
   6632 
   6633   if (!dst_.is(eax)) __ mov(dst_, eax);
   6634 }
   6635 
   6636 
   6637 class DeferredReferenceGetKeyedValue: public DeferredCode {
   6638  public:
   6639   explicit DeferredReferenceGetKeyedValue(Register dst,
   6640                                           Register receiver,
   6641                                           Register key)
   6642       : dst_(dst), receiver_(receiver), key_(key) {
   6643     set_comment("[ DeferredReferenceGetKeyedValue");
   6644   }
   6645 
   6646   virtual void Generate();
   6647 
   6648   Label* patch_site() { return &patch_site_; }
   6649 
   6650  private:
   6651   Label patch_site_;
   6652   Register dst_;
   6653   Register receiver_;
   6654   Register key_;
   6655 };
   6656 
   6657 
   6658 void DeferredReferenceGetKeyedValue::Generate() {
   6659   if (!receiver_.is(eax)) {
   6660     // Register eax is available for key.
   6661     if (!key_.is(eax)) {
   6662       __ mov(eax, key_);
   6663     }
   6664     if (!receiver_.is(edx)) {
   6665       __ mov(edx, receiver_);
   6666     }
   6667   } else if (!key_.is(edx)) {
   6668     // Register edx is available for receiver.
   6669     if (!receiver_.is(edx)) {
   6670       __ mov(edx, receiver_);
   6671     }
   6672     if (!key_.is(eax)) {
   6673       __ mov(eax, key_);
   6674     }
   6675   } else {
   6676     __ xchg(edx, eax);
   6677   }
   6678   // Calculate the delta from the IC call instruction to the map check
   6679   // cmp instruction in the inlined version.  This delta is stored in
   6680   // a test(eax, delta) instruction after the call so that we can find
   6681   // it in the IC initialization code and patch the cmp instruction.
   6682   // This means that we cannot allow test instructions after calls to
   6683   // KeyedLoadIC stubs in other places.
   6684   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
   6685   __ call(ic, RelocInfo::CODE_TARGET);
   6686   // The delta from the start of the map-compare instruction to the
   6687   // test instruction.  We use masm_-> directly here instead of the __
   6688   // macro because the macro sometimes uses macro expansion to turn
   6689   // into something that can't return a value.  This is encountered
   6690   // when doing generated code coverage tests.
   6691   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
   6692   // Here we use masm_-> instead of the __ macro because this is the
   6693   // instruction that gets patched and coverage code gets in the way.
   6694   masm_->test(eax, Immediate(-delta_to_patch_site));
   6695   __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
   6696 
   6697   if (!dst_.is(eax)) __ mov(dst_, eax);
   6698 }
   6699 
   6700 
   6701 class DeferredReferenceSetKeyedValue: public DeferredCode {
   6702  public:
   6703   DeferredReferenceSetKeyedValue(Register value,
   6704                                  Register key,
   6705                                  Register receiver)
   6706       : value_(value), key_(key), receiver_(receiver) {
   6707     set_comment("[ DeferredReferenceSetKeyedValue");
   6708   }
   6709 
   6710   virtual void Generate();
   6711 
   6712   Label* patch_site() { return &patch_site_; }
   6713 
   6714  private:
   6715   Register value_;
   6716   Register key_;
   6717   Register receiver_;
   6718   Label patch_site_;
   6719 };
   6720 
   6721 
   6722 void DeferredReferenceSetKeyedValue::Generate() {
   6723   __ IncrementCounter(&Counters::keyed_store_inline_miss, 1);
   6724   // Push receiver and key arguments on the stack.
   6725   __ push(receiver_);
   6726   __ push(key_);
   6727   // Move value argument to eax as expected by the IC stub.
   6728   if (!value_.is(eax)) __ mov(eax, value_);
   6729   // Call the IC stub.
   6730   Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
   6731   __ call(ic, RelocInfo::CODE_TARGET);
   6732   // The delta from the start of the map-compare instruction to the
   6733   // test instruction.  We use masm_-> directly here instead of the
   6734   // __ macro because the macro sometimes uses macro expansion to turn
   6735   // into something that can't return a value.  This is encountered
   6736   // when doing generated code coverage tests.
   6737   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
   6738   // Here we use masm_-> instead of the __ macro because this is the
   6739   // instruction that gets patched and coverage code gets in the way.
   6740   masm_->test(eax, Immediate(-delta_to_patch_site));
   6741   // Restore value (returned from store IC), key and receiver
   6742   // registers.
   6743   if (!value_.is(eax)) __ mov(value_, eax);
   6744   __ pop(key_);
   6745   __ pop(receiver_);
   6746 }
   6747 
   6748 
   6749 Result CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
   6750 #ifdef DEBUG
   6751   int original_height = frame()->height();
   6752 #endif
   6753   Result result;
   6754   // Do not inline the inobject property case for loads from the global
   6755   // object.  Also do not inline for unoptimized code.  This saves time in
   6756   // the code generator.  Unoptimized code is toplevel code or code that is
   6757   // not in a loop.
   6758   if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
   6759     Comment cmnt(masm(), "[ Load from named Property");
   6760     frame()->Push(name);
   6761 
   6762     RelocInfo::Mode mode = is_contextual
   6763         ? RelocInfo::CODE_TARGET_CONTEXT
   6764         : RelocInfo::CODE_TARGET;
   6765     result = frame()->CallLoadIC(mode);
   6766     // A test eax instruction following the call signals that the inobject
   6767     // property case was inlined.  Ensure that there is not a test eax
   6768     // instruction here.
   6769     __ nop();
   6770   } else {
   6771     // Inline the inobject property case.
   6772     Comment cmnt(masm(), "[ Inlined named property load");
   6773     Result receiver = frame()->Pop();
   6774     receiver.ToRegister();
   6775 
   6776     result = allocator()->Allocate();
   6777     ASSERT(result.is_valid());
   6778     DeferredReferenceGetNamedValue* deferred =
   6779         new DeferredReferenceGetNamedValue(result.reg(), receiver.reg(), name);
   6780 
   6781     // Check that the receiver is a heap object.
   6782     __ test(receiver.reg(), Immediate(kSmiTagMask));
   6783     deferred->Branch(zero);
   6784 
   6785     __ bind(deferred->patch_site());
   6786     // This is the map check instruction that will be patched (so we can't
   6787     // use the double underscore macro that may insert instructions).
   6788     // Initially use an invalid map to force a failure.
   6789     masm()->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
   6790                 Immediate(Factory::null_value()));
   6791     // This branch is always a forwards branch so it's always a fixed size
   6792     // which allows the assert below to succeed and patching to work.
   6793     deferred->Branch(not_equal);
   6794 
   6795     // The delta from the patch label to the load offset must be statically
   6796     // known.
   6797     ASSERT(masm()->SizeOfCodeGeneratedSince(deferred->patch_site()) ==
   6798            LoadIC::kOffsetToLoadInstruction);
   6799     // The initial (invalid) offset has to be large enough to force a 32-bit
   6800     // instruction encoding to allow patching with an arbitrary offset.  Use
   6801     // kMaxInt (minus kHeapObjectTag).
   6802     int offset = kMaxInt;
   6803     masm()->mov(result.reg(), FieldOperand(receiver.reg(), offset));
   6804 
   6805     __ IncrementCounter(&Counters::named_load_inline, 1);
   6806     deferred->BindExit();
   6807   }
   6808   ASSERT(frame()->height() == original_height - 1);
   6809   return result;
   6810 }
   6811 
   6812 
   6813 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
   6814 #ifdef DEBUG
   6815   int expected_height = frame()->height() - (is_contextual ? 1 : 2);
   6816 #endif
   6817   Result result = frame()->CallStoreIC(name, is_contextual);
   6818 
   6819   ASSERT_EQ(expected_height, frame()->height());
   6820   return result;
   6821 }
   6822 
   6823 
   6824 Result CodeGenerator::EmitKeyedLoad() {
   6825 #ifdef DEBUG
   6826   int original_height = frame()->height();
   6827 #endif
   6828   Result result;
   6829   // Inline array load code if inside of a loop.  We do not know the
   6830   // receiver map yet, so we initially generate the code with a check
   6831   // against an invalid map.  In the inline cache code, we patch the map
   6832   // check if appropriate.
   6833   if (loop_nesting() > 0) {
   6834     Comment cmnt(masm_, "[ Inlined load from keyed Property");
   6835 
   6836     Result key = frame_->Pop();
   6837     Result receiver = frame_->Pop();
   6838     key.ToRegister();
   6839     receiver.ToRegister();
   6840 
   6841     // Use a fresh temporary to load the elements without destroying
   6842     // the receiver which is needed for the deferred slow case.
   6843     Result elements = allocator()->Allocate();
   6844     ASSERT(elements.is_valid());
   6845 
   6846     // Use a fresh temporary for the index and later the loaded
   6847     // value.
   6848     result = allocator()->Allocate();
   6849     ASSERT(result.is_valid());
   6850 
   6851     DeferredReferenceGetKeyedValue* deferred =
   6852         new DeferredReferenceGetKeyedValue(result.reg(),
   6853                                            receiver.reg(),
   6854                                            key.reg());
   6855 
   6856     __ test(receiver.reg(), Immediate(kSmiTagMask));
   6857     deferred->Branch(zero);
   6858 
   6859     // Initially, use an invalid map. The map is patched in the IC
   6860     // initialization code.
   6861     __ bind(deferred->patch_site());
   6862     // Use masm-> here instead of the double underscore macro since extra
   6863     // coverage code can interfere with the patching.
   6864     masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
   6865               Immediate(Factory::null_value()));
   6866     deferred->Branch(not_equal);
   6867 
   6868     // Check that the key is a smi.
   6869     __ test(key.reg(), Immediate(kSmiTagMask));
   6870     deferred->Branch(not_zero);
   6871 
   6872     // Get the elements array from the receiver and check that it
   6873     // is not a dictionary.
   6874     __ mov(elements.reg(),
   6875            FieldOperand(receiver.reg(), JSObject::kElementsOffset));
   6876     __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset),
   6877            Immediate(Factory::fixed_array_map()));
   6878     deferred->Branch(not_equal);
   6879 
   6880     // Shift the key to get the actual index value and check that
   6881     // it is within bounds.
   6882     __ mov(result.reg(), key.reg());
   6883     __ SmiUntag(result.reg());
   6884     __ cmp(result.reg(),
   6885            FieldOperand(elements.reg(), FixedArray::kLengthOffset));
   6886     deferred->Branch(above_equal);
   6887 
   6888     // Load and check that the result is not the hole.
   6889     __ mov(result.reg(), Operand(elements.reg(),
   6890                                  result.reg(),
   6891                                  times_4,
   6892                                  FixedArray::kHeaderSize - kHeapObjectTag));
   6893     elements.Unuse();
   6894     __ cmp(Operand(result.reg()), Immediate(Factory::the_hole_value()));
   6895     deferred->Branch(equal);
   6896     __ IncrementCounter(&Counters::keyed_load_inline, 1);
   6897 
   6898     deferred->BindExit();
   6899   } else {
   6900     Comment cmnt(masm_, "[ Load from keyed Property");
   6901     result = frame_->CallKeyedLoadIC(RelocInfo::CODE_TARGET);
   6902     // Make sure that we do not have a test instruction after the
   6903     // call.  A test instruction after the call is used to
   6904     // indicate that we have generated an inline version of the
   6905     // keyed load.  The explicit nop instruction is here because
   6906     // the push that follows might be peep-hole optimized away.
   6907     __ nop();
   6908   }
   6909   ASSERT(frame()->height() == original_height - 2);
   6910   return result;
   6911 }
   6912 
   6913 
   6914 Result CodeGenerator::EmitKeyedStore(StaticType* key_type) {
   6915 #ifdef DEBUG
   6916   int original_height = frame()->height();
   6917 #endif
   6918   Result result;
   6919   // Generate inlined version of the keyed store if the code is in a loop
   6920   // and the key is likely to be a smi.
   6921   if (loop_nesting() > 0 && key_type->IsLikelySmi()) {
   6922     Comment cmnt(masm(), "[ Inlined store to keyed Property");
   6923 
   6924     // Get the receiver, key and value into registers.
   6925     result = frame()->Pop();
   6926     Result key = frame()->Pop();
   6927     Result receiver = frame()->Pop();
   6928 
   6929     Result tmp = allocator_->Allocate();
   6930     ASSERT(tmp.is_valid());
   6931 
   6932     // Determine whether the value is a constant before putting it in a
   6933     // register.
   6934     bool value_is_constant = result.is_constant();
   6935 
   6936     // Make sure that value, key and receiver are in registers.
   6937     result.ToRegister();
   6938     key.ToRegister();
   6939     receiver.ToRegister();
   6940 
   6941     DeferredReferenceSetKeyedValue* deferred =
   6942         new DeferredReferenceSetKeyedValue(result.reg(),
   6943                                            key.reg(),
   6944                                            receiver.reg());
   6945 
   6946     // Check that the value is a smi if it is not a constant.  We can skip
   6947     // the write barrier for smis and constants.
   6948     if (!value_is_constant) {
   6949       __ test(result.reg(), Immediate(kSmiTagMask));
   6950       deferred->Branch(not_zero);
   6951     }
   6952 
   6953     // Check that the key is a non-negative smi.
   6954     __ test(key.reg(), Immediate(kSmiTagMask | 0x80000000));
   6955     deferred->Branch(not_zero);
   6956 
   6957     // Check that the receiver is not a smi.
   6958     __ test(receiver.reg(), Immediate(kSmiTagMask));
   6959     deferred->Branch(zero);
   6960 
   6961     // Check that the receiver is a JSArray.
   6962     __ mov(tmp.reg(),
   6963            FieldOperand(receiver.reg(), HeapObject::kMapOffset));
   6964     __ movzx_b(tmp.reg(),
   6965                FieldOperand(tmp.reg(), Map::kInstanceTypeOffset));
   6966     __ cmp(tmp.reg(), JS_ARRAY_TYPE);
   6967     deferred->Branch(not_equal);
   6968 
   6969     // Check that the key is within bounds.  Both the key and the length of
   6970     // the JSArray are smis.
   6971     __ cmp(key.reg(),
   6972            FieldOperand(receiver.reg(), JSArray::kLengthOffset));
   6973     deferred->Branch(greater_equal);
   6974 
   6975     // Get the elements array from the receiver and check that it is not a
   6976     // dictionary.
   6977     __ mov(tmp.reg(),
   6978            FieldOperand(receiver.reg(), JSObject::kElementsOffset));
   6979     // Bind the deferred code patch site to be able to locate the fixed
   6980     // array map comparison.  When debugging, we patch this comparison to
   6981     // always fail so that we will hit the IC call in the deferred code
   6982     // which will allow the debugger to break for fast case stores.
   6983     __ bind(deferred->patch_site());
   6984     __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
   6985            Immediate(Factory::fixed_array_map()));
   6986     deferred->Branch(not_equal);
   6987 
   6988     // Store the value.
   6989     __ mov(Operand(tmp.reg(),
   6990                    key.reg(),
   6991                    times_2,
   6992                    FixedArray::kHeaderSize - kHeapObjectTag),
   6993            result.reg());
   6994     __ IncrementCounter(&Counters::keyed_store_inline, 1);
   6995 
   6996     deferred->BindExit();
   6997   } else {
   6998     result = frame()->CallKeyedStoreIC();
   6999     // Make sure that we do not have a test instruction after the
   7000     // call.  A test instruction after the call is used to
   7001     // indicate that we have generated an inline version of the
   7002     // keyed store.
   7003     __ nop();
   7004     frame()->Drop(2);
   7005   }
   7006   ASSERT(frame()->height() == original_height - 3);
   7007   return result;
   7008 }
   7009 
   7010 
   7011 #undef __
   7012 #define __ ACCESS_MASM(masm)
   7013 
   7014 
   7015 Handle<String> Reference::GetName() {
   7016   ASSERT(type_ == NAMED);
   7017   Property* property = expression_->AsProperty();
   7018   if (property == NULL) {
   7019     // Global variable reference treated as a named property reference.
   7020     VariableProxy* proxy = expression_->AsVariableProxy();
   7021     ASSERT(proxy->AsVariable() != NULL);
   7022     ASSERT(proxy->AsVariable()->is_global());
   7023     return proxy->name();
   7024   } else {
   7025     Literal* raw_name = property->key()->AsLiteral();
   7026     ASSERT(raw_name != NULL);
   7027     return Handle<String>::cast(raw_name->handle());
   7028   }
   7029 }
   7030 
   7031 
   7032 void Reference::GetValue() {
   7033   ASSERT(!cgen_->in_spilled_code());
   7034   ASSERT(cgen_->HasValidEntryRegisters());
   7035   ASSERT(!is_illegal());
   7036   MacroAssembler* masm = cgen_->masm();
   7037 
   7038   // Record the source position for the property load.
   7039   Property* property = expression_->AsProperty();
   7040   if (property != NULL) {
   7041     cgen_->CodeForSourcePosition(property->position());
   7042   }
   7043 
   7044   switch (type_) {
   7045     case SLOT: {
   7046       Comment cmnt(masm, "[ Load from Slot");
   7047       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
   7048       ASSERT(slot != NULL);
   7049       Result result =
   7050           cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
   7051       if (!persist_after_get_) set_unloaded();
   7052       cgen_->frame()->Push(&result);
   7053       break;
   7054     }
   7055 
   7056     case NAMED: {
   7057       Variable* var = expression_->AsVariableProxy()->AsVariable();
   7058       bool is_global = var != NULL;
   7059       ASSERT(!is_global || var->is_global());
   7060       if (persist_after_get_) cgen_->frame()->Dup();
   7061       Result result = cgen_->EmitNamedLoad(GetName(), is_global);
   7062       if (!persist_after_get_) set_unloaded();
   7063       cgen_->frame()->Push(&result);
   7064       break;
   7065     }
   7066 
   7067     case KEYED: {
   7068       if (persist_after_get_) {
   7069         cgen_->frame()->PushElementAt(1);
   7070         cgen_->frame()->PushElementAt(1);
   7071       }
   7072       Result value = cgen_->EmitKeyedLoad();
   7073       cgen_->frame()->Push(&value);
   7074       if (!persist_after_get_) set_unloaded();
   7075       break;
   7076     }
   7077 
   7078     default:
   7079       UNREACHABLE();
   7080   }
   7081 }
   7082 
   7083 
   7084 void Reference::TakeValue() {
   7085   // For non-constant frame-allocated slots, we invalidate the value in the
   7086   // slot.  For all others, we fall back on GetValue.
   7087   ASSERT(!cgen_->in_spilled_code());
   7088   ASSERT(!is_illegal());
   7089   if (type_ != SLOT) {
   7090     GetValue();
   7091     return;
   7092   }
   7093 
   7094   Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
   7095   ASSERT(slot != NULL);
   7096   if (slot->type() == Slot::LOOKUP ||
   7097       slot->type() == Slot::CONTEXT ||
   7098       slot->var()->mode() == Variable::CONST ||
   7099       slot->is_arguments()) {
   7100     GetValue();
   7101     return;
   7102   }
   7103 
   7104   // Only non-constant, frame-allocated parameters and locals can
   7105   // reach here. Be careful not to use the optimizations for arguments
   7106   // object access since it may not have been initialized yet.
   7107   ASSERT(!slot->is_arguments());
   7108   if (slot->type() == Slot::PARAMETER) {
   7109     cgen_->frame()->TakeParameterAt(slot->index());
   7110   } else {
   7111     ASSERT(slot->type() == Slot::LOCAL);
   7112     cgen_->frame()->TakeLocalAt(slot->index());
   7113   }
   7114 
   7115   ASSERT(persist_after_get_);
   7116   // Do not unload the reference, because it is used in SetValue.
   7117 }
   7118 
   7119 
   7120 void Reference::SetValue(InitState init_state) {
   7121   ASSERT(cgen_->HasValidEntryRegisters());
   7122   ASSERT(!is_illegal());
   7123   MacroAssembler* masm = cgen_->masm();
   7124   switch (type_) {
   7125     case SLOT: {
   7126       Comment cmnt(masm, "[ Store to Slot");
   7127       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
   7128       ASSERT(slot != NULL);
   7129       cgen_->StoreToSlot(slot, init_state);
   7130       set_unloaded();
   7131       break;
   7132     }
   7133 
   7134     case NAMED: {
   7135       Comment cmnt(masm, "[ Store to named Property");
   7136       Result answer = cgen_->EmitNamedStore(GetName(), false);
   7137       cgen_->frame()->Push(&answer);
   7138       set_unloaded();
   7139       break;
   7140     }
   7141 
   7142     case KEYED: {
   7143       Comment cmnt(masm, "[ Store to keyed Property");
   7144       Property* property = expression()->AsProperty();
   7145       ASSERT(property != NULL);
   7146       Result answer = cgen_->EmitKeyedStore(property->key()->type());
   7147       cgen_->frame()->Push(&answer);
   7148       set_unloaded();
   7149       break;
   7150     }
   7151 
   7152     case UNLOADED:
   7153     case ILLEGAL:
   7154       UNREACHABLE();
   7155   }
   7156 }
   7157 
   7158 
   7159 void FastNewClosureStub::Generate(MacroAssembler* masm) {
   7160   // Clone the boilerplate in new space. Set the context to the
   7161   // current context in esi.
   7162   Label gc;
   7163   __ AllocateInNewSpace(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
   7164 
   7165   // Get the boilerplate function from the stack.
   7166   __ mov(edx, Operand(esp, 1 * kPointerSize));
   7167 
   7168   // Compute the function map in the current global context and set that
   7169   // as the map of the allocated object.
   7170   __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   7171   __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
   7172   __ mov(ecx, Operand(ecx, Context::SlotOffset(Context::FUNCTION_MAP_INDEX)));
   7173   __ mov(FieldOperand(eax, JSObject::kMapOffset), ecx);
   7174 
   7175   // Clone the rest of the boilerplate fields. We don't have to update
   7176   // the write barrier because the allocated object is in new space.
   7177   for (int offset = kPointerSize;
   7178        offset < JSFunction::kSize;
   7179        offset += kPointerSize) {
   7180     if (offset == JSFunction::kContextOffset) {
   7181       __ mov(FieldOperand(eax, offset), esi);
   7182     } else {
   7183       __ mov(ebx, FieldOperand(edx, offset));
   7184       __ mov(FieldOperand(eax, offset), ebx);
   7185     }
   7186   }
   7187 
   7188   // Return and remove the on-stack parameter.
   7189   __ ret(1 * kPointerSize);
   7190 
   7191   // Create a new closure through the slower runtime call.
   7192   __ bind(&gc);
   7193   __ pop(ecx);  // Temporarily remove return address.
   7194   __ pop(edx);
   7195   __ push(esi);
   7196   __ push(edx);
   7197   __ push(ecx);  // Restore return address.
   7198   __ TailCallRuntime(ExternalReference(Runtime::kNewClosure), 2, 1);
   7199 }
   7200 
   7201 
   7202 void FastNewContextStub::Generate(MacroAssembler* masm) {
   7203   // Try to allocate the context in new space.
   7204   Label gc;
   7205   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
   7206   __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
   7207                         eax, ebx, ecx, &gc, TAG_OBJECT);
   7208 
   7209   // Get the function from the stack.
   7210   __ mov(ecx, Operand(esp, 1 * kPointerSize));
   7211 
   7212   // Setup the object header.
   7213   __ mov(FieldOperand(eax, HeapObject::kMapOffset), Factory::context_map());
   7214   __ mov(FieldOperand(eax, Array::kLengthOffset), Immediate(length));
   7215 
   7216   // Setup the fixed slots.
   7217   __ xor_(ebx, Operand(ebx));  // Set to NULL.
   7218   __ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx);
   7219   __ mov(Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)), eax);
   7220   __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), ebx);
   7221   __ mov(Operand(eax, Context::SlotOffset(Context::EXTENSION_INDEX)), ebx);
   7222 
   7223   // Copy the global object from the surrounding context. We go through the
   7224   // context in the function (ecx) to match the allocation behavior we have
   7225   // in the runtime system (see Heap::AllocateFunctionContext).
   7226   __ mov(ebx, FieldOperand(ecx, JSFunction::kContextOffset));
   7227   __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX)));
   7228   __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
   7229 
   7230   // Initialize the rest of the slots to undefined.
   7231   __ mov(ebx, Factory::undefined_value());
   7232   for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
   7233     __ mov(Operand(eax, Context::SlotOffset(i)), ebx);
   7234   }
   7235 
   7236   // Return and remove the on-stack parameter.
   7237   __ mov(esi, Operand(eax));
   7238   __ ret(1 * kPointerSize);
   7239 
   7240   // Need to collect. Call into runtime system.
   7241   __ bind(&gc);
   7242   __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1);
   7243 }
   7244 
   7245 
   7246 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
   7247   // Stack layout on entry:
   7248   //
   7249   // [esp + kPointerSize]: constant elements.
   7250   // [esp + (2 * kPointerSize)]: literal index.
   7251   // [esp + (3 * kPointerSize)]: literals array.
   7252 
   7253   // All sizes here are multiples of kPointerSize.
   7254   int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
   7255   int size = JSArray::kSize + elements_size;
   7256 
   7257   // Load boilerplate object into ecx and check if we need to create a
   7258   // boilerplate.
   7259   Label slow_case;
   7260   __ mov(ecx, Operand(esp, 3 * kPointerSize));
   7261   __ mov(eax, Operand(esp, 2 * kPointerSize));
   7262   ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
   7263   __ mov(ecx, FieldOperand(ecx, eax, times_2, FixedArray::kHeaderSize));
   7264   __ cmp(ecx, Factory::undefined_value());
   7265   __ j(equal, &slow_case);
   7266 
   7267   // Allocate both the JS array and the elements array in one big
   7268   // allocation. This avoids multiple limit checks.
   7269   __ AllocateInNewSpace(size, eax, ebx, edx, &slow_case, TAG_OBJECT);
   7270 
   7271   // Copy the JS array part.
   7272   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
   7273     if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
   7274       __ mov(ebx, FieldOperand(ecx, i));
   7275       __ mov(FieldOperand(eax, i), ebx);
   7276     }
   7277   }
   7278 
   7279   if (length_ > 0) {
   7280     // Get hold of the elements array of the boilerplate and setup the
   7281     // elements pointer in the resulting object.
   7282     __ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset));
   7283     __ lea(edx, Operand(eax, JSArray::kSize));
   7284     __ mov(FieldOperand(eax, JSArray::kElementsOffset), edx);
   7285 
   7286     // Copy the elements array.
   7287     for (int i = 0; i < elements_size; i += kPointerSize) {
   7288       __ mov(ebx, FieldOperand(ecx, i));
   7289       __ mov(FieldOperand(edx, i), ebx);
   7290     }
   7291   }
   7292 
   7293   // Return and remove the on-stack parameters.
   7294   __ ret(3 * kPointerSize);
   7295 
   7296   __ bind(&slow_case);
   7297   ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
   7298   __ TailCallRuntime(runtime, 3, 1);
   7299 }
   7300 
   7301 
   7302 // NOTE: The stub does not handle the inlined cases (Smis, Booleans, undefined).
   7303 void ToBooleanStub::Generate(MacroAssembler* masm) {
   7304   Label false_result, true_result, not_string;
   7305   __ mov(eax, Operand(esp, 1 * kPointerSize));
   7306 
   7307   // 'null' => false.
   7308   __ cmp(eax, Factory::null_value());
   7309   __ j(equal, &false_result);
   7310 
   7311   // Get the map and type of the heap object.
   7312   __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
   7313   __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
   7314 
   7315   // Undetectable => false.
   7316   __ movzx_b(ebx, FieldOperand(edx, Map::kBitFieldOffset));
   7317   __ and_(ebx, 1 << Map::kIsUndetectable);
   7318   __ j(not_zero, &false_result);
   7319 
   7320   // JavaScript object => true.
   7321   __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
   7322   __ j(above_equal, &true_result);
   7323 
   7324   // String value => false iff empty.
   7325   __ cmp(ecx, FIRST_NONSTRING_TYPE);
   7326   __ j(above_equal, &not_string);
   7327   __ mov(edx, FieldOperand(eax, String::kLengthOffset));
   7328   __ test(edx, Operand(edx));
   7329   __ j(zero, &false_result);
   7330   __ jmp(&true_result);
   7331 
   7332   __ bind(&not_string);
   7333   // HeapNumber => false iff +0, -0, or NaN.
   7334   __ cmp(edx, Factory::heap_number_map());
   7335   __ j(not_equal, &true_result);
   7336   __ fldz();
   7337   __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
   7338   __ FCmp();
   7339   __ j(zero, &false_result);
   7340   // Fall through to |true_result|.
   7341 
   7342   // Return 1/0 for true/false in eax.
   7343   __ bind(&true_result);
   7344   __ mov(eax, 1);
   7345   __ ret(1 * kPointerSize);
   7346   __ bind(&false_result);
   7347   __ mov(eax, 0);
   7348   __ ret(1 * kPointerSize);
   7349 }
   7350 
   7351 
   7352 void GenericBinaryOpStub::GenerateCall(
   7353     MacroAssembler* masm,
   7354     Register left,
   7355     Register right) {
   7356   if (!ArgsInRegistersSupported()) {
   7357     // Pass arguments on the stack.
   7358     __ push(left);
   7359     __ push(right);
   7360   } else {
   7361     // The calling convention with registers is left in edx and right in eax.
   7362     Register left_arg = edx;
   7363     Register right_arg = eax;
   7364     if (!(left.is(left_arg) && right.is(right_arg))) {
   7365       if (left.is(right_arg) && right.is(left_arg)) {
   7366         if (IsOperationCommutative()) {
   7367           SetArgsReversed();
   7368         } else {
   7369           __ xchg(left, right);
   7370         }
   7371       } else if (left.is(left_arg)) {
   7372         __ mov(right_arg, right);
   7373       } else if (right.is(right_arg)) {
   7374         __ mov(left_arg, left);
   7375       } else if (left.is(right_arg)) {
   7376         if (IsOperationCommutative()) {
   7377           __ mov(left_arg, right);
   7378           SetArgsReversed();
   7379         } else {
   7380           // Order of moves important to avoid destroying left argument.
   7381           __ mov(left_arg, left);
   7382           __ mov(right_arg, right);
   7383         }
   7384       } else if (right.is(left_arg)) {
   7385         if (IsOperationCommutative()) {
   7386           __ mov(right_arg, left);
   7387           SetArgsReversed();
   7388         } else {
   7389           // Order of moves important to avoid destroying right argument.
   7390           __ mov(right_arg, right);
   7391           __ mov(left_arg, left);
   7392         }
   7393       } else {
   7394         // Order of moves is not important.
   7395         __ mov(left_arg, left);
   7396         __ mov(right_arg, right);
   7397       }
   7398     }
   7399 
   7400     // Update flags to indicate that arguments are in registers.
   7401     SetArgsInRegisters();
   7402     __ IncrementCounter(&Counters::generic_binary_stub_calls_regs, 1);
   7403   }
   7404 
   7405   // Call the stub.
   7406   __ CallStub(this);
   7407 }
   7408 
   7409 
   7410 void GenericBinaryOpStub::GenerateCall(
   7411     MacroAssembler* masm,
   7412     Register left,
   7413     Smi* right) {
   7414   if (!ArgsInRegistersSupported()) {
   7415     // Pass arguments on the stack.
   7416     __ push(left);
   7417     __ push(Immediate(right));
   7418   } else {
   7419     // The calling convention with registers is left in edx and right in eax.
   7420     Register left_arg = edx;
   7421     Register right_arg = eax;
   7422     if (left.is(left_arg)) {
   7423       __ mov(right_arg, Immediate(right));
   7424     } else if (left.is(right_arg) && IsOperationCommutative()) {
   7425       __ mov(left_arg, Immediate(right));
   7426       SetArgsReversed();
   7427     } else {
   7428       // For non-commutative operations, left and right_arg might be
   7429       // the same register.  Therefore, the order of the moves is
   7430       // important here in order to not overwrite left before moving
   7431       // it to left_arg.
   7432       __ mov(left_arg, left);
   7433       __ mov(right_arg, Immediate(right));
   7434     }
   7435 
   7436     // Update flags to indicate that arguments are in registers.
   7437     SetArgsInRegisters();
   7438     __ IncrementCounter(&Counters::generic_binary_stub_calls_regs, 1);
   7439   }
   7440 
   7441   // Call the stub.
   7442   __ CallStub(this);
   7443 }
   7444 
   7445 
   7446 void GenericBinaryOpStub::GenerateCall(
   7447     MacroAssembler* masm,
   7448     Smi* left,
   7449     Register right) {
   7450   if (!ArgsInRegistersSupported()) {
   7451     // Pass arguments on the stack.
   7452     __ push(Immediate(left));
   7453     __ push(right);
   7454   } else {
   7455     // The calling convention with registers is left in edx and right in eax.
   7456     Register left_arg = edx;
   7457     Register right_arg = eax;
   7458     if (right.is(right_arg)) {
   7459       __ mov(left_arg, Immediate(left));
   7460     } else if (right.is(left_arg) && IsOperationCommutative()) {
   7461       __ mov(right_arg, Immediate(left));
   7462       SetArgsReversed();
   7463     } else {
   7464       // For non-commutative operations, right and left_arg might be
   7465       // the same register.  Therefore, the order of the moves is
   7466       // important here in order to not overwrite right before moving
   7467       // it to right_arg.
   7468       __ mov(right_arg, right);
   7469       __ mov(left_arg, Immediate(left));
   7470     }
   7471     // Update flags to indicate that arguments are in registers.
   7472     SetArgsInRegisters();
   7473     __ IncrementCounter(&Counters::generic_binary_stub_calls_regs, 1);
   7474   }
   7475 
   7476   // Call the stub.
   7477   __ CallStub(this);
   7478 }
   7479 
   7480 
   7481 Result GenericBinaryOpStub::GenerateCall(MacroAssembler* masm,
   7482                                          VirtualFrame* frame,
   7483                                          Result* left,
   7484                                          Result* right) {
   7485   if (ArgsInRegistersSupported()) {
   7486     SetArgsInRegisters();
   7487     return frame->CallStub(this, left, right);
   7488   } else {
   7489     frame->Push(left);
   7490     frame->Push(right);
   7491     return frame->CallStub(this, 2);
   7492   }
   7493 }
   7494 
   7495 
   7496 void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
   7497   // 1. Move arguments into edx, eax except for DIV and MOD, which need the
   7498   // dividend in eax and edx free for the division.  Use eax, ebx for those.
   7499   Comment load_comment(masm, "-- Load arguments");
   7500   Register left = edx;
   7501   Register right = eax;
   7502   if (op_ == Token::DIV || op_ == Token::MOD) {
   7503     left = eax;
   7504     right = ebx;
   7505     if (HasArgsInRegisters()) {
   7506       __ mov(ebx, eax);
   7507       __ mov(eax, edx);
   7508     }
   7509   }
   7510   if (!HasArgsInRegisters()) {
   7511     __ mov(right, Operand(esp, 1 * kPointerSize));
   7512     __ mov(left, Operand(esp, 2 * kPointerSize));
   7513   }
   7514 
   7515   // 2. Prepare the smi check of both operands by oring them together.
   7516   Comment smi_check_comment(masm, "-- Smi check arguments");
   7517   Label not_smis;
   7518   Register combined = ecx;
   7519   ASSERT(!left.is(combined) && !right.is(combined));
   7520   switch (op_) {
   7521     case Token::BIT_OR:
   7522       // Perform the operation into eax and smi check the result.  Preserve
   7523       // eax in case the result is not a smi.
   7524       ASSERT(!left.is(ecx) && !right.is(ecx));
   7525       __ mov(ecx, right);
   7526       __ or_(right, Operand(left));  // Bitwise or is commutative.
   7527       combined = right;
   7528       break;
   7529 
   7530     case Token::BIT_XOR:
   7531     case Token::BIT_AND:
   7532     case Token::ADD:
   7533     case Token::SUB:
   7534     case Token::MUL:
   7535     case Token::DIV:
   7536     case Token::MOD:
   7537       __ mov(combined, right);
   7538       __ or_(combined, Operand(left));
   7539       break;
   7540 
   7541     case Token::SHL:
   7542     case Token::SAR:
   7543     case Token::SHR:
   7544       // Move the right operand into ecx for the shift operation, use eax
   7545       // for the smi check register.
   7546       ASSERT(!left.is(ecx) && !right.is(ecx));
   7547       __ mov(ecx, right);
   7548       __ or_(right, Operand(left));
   7549       combined = right;
   7550       break;
   7551 
   7552     default:
   7553       break;
   7554   }
   7555 
   7556   // 3. Perform the smi check of the operands.
   7557   ASSERT(kSmiTag == 0);  // Adjust zero check if not the case.
   7558   __ test(combined, Immediate(kSmiTagMask));
   7559   __ j(not_zero, &not_smis, not_taken);
   7560 
   7561   // 4. Operands are both smis, perform the operation leaving the result in
   7562   // eax and check the result if necessary.
   7563   Comment perform_smi(masm, "-- Perform smi operation");
   7564   Label use_fp_on_smis;
   7565   switch (op_) {
   7566     case Token::BIT_OR:
   7567       // Nothing to do.
   7568       break;
   7569 
   7570     case Token::BIT_XOR:
   7571       ASSERT(right.is(eax));
   7572       __ xor_(right, Operand(left));  // Bitwise xor is commutative.
   7573       break;
   7574 
   7575     case Token::BIT_AND:
   7576       ASSERT(right.is(eax));
   7577       __ and_(right, Operand(left));  // Bitwise and is commutative.
   7578       break;
   7579 
   7580     case Token::SHL:
   7581       // Remove tags from operands (but keep sign).
   7582       __ SmiUntag(left);
   7583       __ SmiUntag(ecx);
   7584       // Perform the operation.
   7585       __ shl_cl(left);
   7586       // Check that the *signed* result fits in a smi.
   7587       __ cmp(left, 0xc0000000);
   7588       __ j(sign, &use_fp_on_smis, not_taken);
   7589       // Tag the result and store it in register eax.
   7590       __ SmiTag(left);
   7591       __ mov(eax, left);
   7592       break;
   7593 
   7594     case Token::SAR:
   7595       // Remove tags from operands (but keep sign).
   7596       __ SmiUntag(left);
   7597       __ SmiUntag(ecx);
   7598       // Perform the operation.
   7599       __ sar_cl(left);
   7600       // Tag the result and store it in register eax.
   7601       __ SmiTag(left);
   7602       __ mov(eax, left);
   7603       break;
   7604 
   7605     case Token::SHR:
   7606       // Remove tags from operands (but keep sign).
   7607       __ SmiUntag(left);
   7608       __ SmiUntag(ecx);
   7609       // Perform the operation.
   7610       __ shr_cl(left);
   7611       // Check that the *unsigned* result fits in a smi.
   7612       // Neither of the two high-order bits can be set:
   7613       // - 0x80000000: high bit would be lost when smi tagging.
   7614       // - 0x40000000: this number would convert to negative when
   7615       // Smi tagging these two cases can only happen with shifts
   7616       // by 0 or 1 when handed a valid smi.
   7617       __ test(left, Immediate(0xc0000000));
   7618       __ j(not_zero, slow, not_taken);
   7619       // Tag the result and store it in register eax.
   7620       __ SmiTag(left);
   7621       __ mov(eax, left);
   7622       break;
   7623 
   7624     case Token::ADD:
   7625       ASSERT(right.is(eax));
   7626       __ add(right, Operand(left));  // Addition is commutative.
   7627       __ j(overflow, &use_fp_on_smis, not_taken);
   7628       break;
   7629 
   7630     case Token::SUB:
   7631       __ sub(left, Operand(right));
   7632       __ j(overflow, &use_fp_on_smis, not_taken);
   7633       __ mov(eax, left);
   7634       break;
   7635 
   7636     case Token::MUL:
   7637       // If the smi tag is 0 we can just leave the tag on one operand.
   7638       ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
   7639       // We can't revert the multiplication if the result is not a smi
   7640       // so save the right operand.
   7641       __ mov(ebx, right);
   7642       // Remove tag from one of the operands (but keep sign).
   7643       __ SmiUntag(right);
   7644       // Do multiplication.
   7645       __ imul(right, Operand(left));  // Multiplication is commutative.
   7646       __ j(overflow, &use_fp_on_smis, not_taken);
   7647       // Check for negative zero result.  Use combined = left | right.
   7648       __ NegativeZeroTest(right, combined, &use_fp_on_smis);
   7649       break;
   7650 
   7651     case Token::DIV:
   7652       // We can't revert the division if the result is not a smi so
   7653       // save the left operand.
   7654       __ mov(edi, left);
   7655       // Check for 0 divisor.
   7656       __ test(right, Operand(right));
   7657       __ j(zero, &use_fp_on_smis, not_taken);
   7658       // Sign extend left into edx:eax.
   7659       ASSERT(left.is(eax));
   7660       __ cdq();
   7661       // Divide edx:eax by right.
   7662       __ idiv(right);
   7663       // Check for the corner case of dividing the most negative smi by
   7664       // -1. We cannot use the overflow flag, since it is not set by idiv
   7665       // instruction.
   7666       ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
   7667       __ cmp(eax, 0x40000000);
   7668       __ j(equal, &use_fp_on_smis);
   7669       // Check for negative zero result.  Use combined = left | right.
   7670       __ NegativeZeroTest(eax, combined, &use_fp_on_smis);
   7671       // Check that the remainder is zero.
   7672       __ test(edx, Operand(edx));
   7673       __ j(not_zero, &use_fp_on_smis);
   7674       // Tag the result and store it in register eax.
   7675       __ SmiTag(eax);
   7676       break;
   7677 
   7678     case Token::MOD:
   7679       // Check for 0 divisor.
   7680       __ test(right, Operand(right));
   7681       __ j(zero, &not_smis, not_taken);
   7682 
   7683       // Sign extend left into edx:eax.
   7684       ASSERT(left.is(eax));
   7685       __ cdq();
   7686       // Divide edx:eax by right.
   7687       __ idiv(right);
   7688       // Check for negative zero result.  Use combined = left | right.
   7689       __ NegativeZeroTest(edx, combined, slow);
   7690       // Move remainder to register eax.
   7691       __ mov(eax, edx);
   7692       break;
   7693 
   7694     default:
   7695       UNREACHABLE();
   7696   }
   7697 
   7698   // 5. Emit return of result in eax.
   7699   GenerateReturn(masm);
   7700 
   7701   // 6. For some operations emit inline code to perform floating point
   7702   // operations on known smis (e.g., if the result of the operation
   7703   // overflowed the smi range).
   7704   switch (op_) {
   7705     case Token::SHL: {
   7706       Comment perform_float(masm, "-- Perform float operation on smis");
   7707       __ bind(&use_fp_on_smis);
   7708       // Result we want is in left == edx, so we can put the allocated heap
   7709       // number in eax.
   7710       __ AllocateHeapNumber(eax, ecx, ebx, slow);
   7711       // Store the result in the HeapNumber and return.
   7712       if (CpuFeatures::IsSupported(SSE2)) {
   7713         CpuFeatures::Scope use_sse2(SSE2);
   7714         __ cvtsi2sd(xmm0, Operand(left));
   7715         __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
   7716       } else {
   7717         // It's OK to overwrite the right argument on the stack because we
   7718         // are about to return.
   7719         __ mov(Operand(esp, 1 * kPointerSize), left);
   7720         __ fild_s(Operand(esp, 1 * kPointerSize));
   7721         __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
   7722       }
   7723       GenerateReturn(masm);
   7724       break;
   7725     }
   7726 
   7727     case Token::ADD:
   7728     case Token::SUB:
   7729     case Token::MUL:
   7730     case Token::DIV: {
   7731       Comment perform_float(masm, "-- Perform float operation on smis");
   7732       __ bind(&use_fp_on_smis);
   7733       // Restore arguments to edx, eax.
   7734       switch (op_) {
   7735         case Token::ADD:
   7736           // Revert right = right + left.
   7737           __ sub(right, Operand(left));
   7738           break;
   7739         case Token::SUB:
   7740           // Revert left = left - right.
   7741           __ add(left, Operand(right));
   7742           break;
   7743         case Token::MUL:
   7744           // Right was clobbered but a copy is in ebx.
   7745           __ mov(right, ebx);
   7746           break;
   7747         case Token::DIV:
   7748           // Left was clobbered but a copy is in edi.  Right is in ebx for
   7749           // division.
   7750           __ mov(edx, edi);
   7751           __ mov(eax, right);
   7752           break;
   7753         default: UNREACHABLE();
   7754           break;
   7755       }
   7756       __ AllocateHeapNumber(ecx, ebx, no_reg, slow);
   7757       if (CpuFeatures::IsSupported(SSE2)) {
   7758         CpuFeatures::Scope use_sse2(SSE2);
   7759         FloatingPointHelper::LoadSSE2Smis(masm, ebx);
   7760         switch (op_) {
   7761           case Token::ADD: __ addsd(xmm0, xmm1); break;
   7762           case Token::SUB: __ subsd(xmm0, xmm1); break;
   7763           case Token::MUL: __ mulsd(xmm0, xmm1); break;
   7764           case Token::DIV: __ divsd(xmm0, xmm1); break;
   7765           default: UNREACHABLE();
   7766         }
   7767         __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0);
   7768       } else {  // SSE2 not available, use FPU.
   7769         FloatingPointHelper::LoadFloatSmis(masm, ebx);
   7770         switch (op_) {
   7771           case Token::ADD: __ faddp(1); break;
   7772           case Token::SUB: __ fsubp(1); break;
   7773           case Token::MUL: __ fmulp(1); break;
   7774           case Token::DIV: __ fdivp(1); break;
   7775           default: UNREACHABLE();
   7776         }
   7777         __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset));
   7778       }
   7779       __ mov(eax, ecx);
   7780       GenerateReturn(masm);
   7781       break;
   7782     }
   7783 
   7784     default:
   7785       break;
   7786   }
   7787 
   7788   // 7. Non-smi operands, fall out to the non-smi code with the operands in
   7789   // edx and eax.
   7790   Comment done_comment(masm, "-- Enter non-smi code");
   7791   __ bind(&not_smis);
   7792   switch (op_) {
   7793     case Token::BIT_OR:
   7794     case Token::SHL:
   7795     case Token::SAR:
   7796     case Token::SHR:
   7797       // Right operand is saved in ecx and eax was destroyed by the smi
   7798       // check.
   7799       __ mov(eax, ecx);
   7800       break;
   7801 
   7802     case Token::DIV:
   7803     case Token::MOD:
   7804       // Operands are in eax, ebx at this point.
   7805       __ mov(edx, eax);
   7806       __ mov(eax, ebx);
   7807       break;
   7808 
   7809     default:
   7810       break;
   7811   }
   7812 }
   7813 
   7814 
   7815 void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
   7816   Label call_runtime;
   7817 
   7818   __ IncrementCounter(&Counters::generic_binary_stub_calls, 1);
   7819 
   7820   // Generate fast case smi code if requested. This flag is set when the fast
   7821   // case smi code is not generated by the caller. Generating it here will speed
   7822   // up common operations.
   7823   if (HasSmiCodeInStub()) {
   7824     GenerateSmiCode(masm, &call_runtime);
   7825   } else if (op_ != Token::MOD) {  // MOD goes straight to runtime.
   7826     GenerateLoadArguments(masm);
   7827   }
   7828 
   7829   // Floating point case.
   7830   switch (op_) {
   7831     case Token::ADD:
   7832     case Token::SUB:
   7833     case Token::MUL:
   7834     case Token::DIV: {
   7835       if (CpuFeatures::IsSupported(SSE2)) {
   7836         CpuFeatures::Scope use_sse2(SSE2);
   7837         if (NumberInfo::IsNumber(operands_type_)) {
   7838           if (FLAG_debug_code) {
   7839             // Assert at runtime that inputs are only numbers.
   7840             __ AbortIfNotNumber(edx,
   7841                                 "GenericBinaryOpStub operand not a number.");
   7842             __ AbortIfNotNumber(eax,
   7843                                 "GenericBinaryOpStub operand not a number.");
   7844           }
   7845           FloatingPointHelper::LoadSSE2Operands(masm);
   7846         } else {
   7847           FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime);
   7848         }
   7849 
   7850         switch (op_) {
   7851           case Token::ADD: __ addsd(xmm0, xmm1); break;
   7852           case Token::SUB: __ subsd(xmm0, xmm1); break;
   7853           case Token::MUL: __ mulsd(xmm0, xmm1); break;
   7854           case Token::DIV: __ divsd(xmm0, xmm1); break;
   7855           default: UNREACHABLE();
   7856         }
   7857         GenerateHeapResultAllocation(masm, &call_runtime);
   7858         __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
   7859         GenerateReturn(masm);
   7860       } else {  // SSE2 not available, use FPU.
   7861         if (NumberInfo::IsNumber(operands_type_)) {
   7862           if (FLAG_debug_code) {
   7863             // Assert at runtime that inputs are only numbers.
   7864             __ AbortIfNotNumber(edx,
   7865                                 "GenericBinaryOpStub operand not a number.");
   7866             __ AbortIfNotNumber(eax,
   7867                                 "GenericBinaryOpStub operand not a number.");
   7868           }
   7869         } else {
   7870           FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx);
   7871         }
   7872         FloatingPointHelper::LoadFloatOperands(
   7873             masm,
   7874             ecx,
   7875             FloatingPointHelper::ARGS_IN_REGISTERS);
   7876         switch (op_) {
   7877           case Token::ADD: __ faddp(1); break;
   7878           case Token::SUB: __ fsubp(1); break;
   7879           case Token::MUL: __ fmulp(1); break;
   7880           case Token::DIV: __ fdivp(1); break;
   7881           default: UNREACHABLE();
   7882         }
   7883         Label after_alloc_failure;
   7884         GenerateHeapResultAllocation(masm, &after_alloc_failure);
   7885         __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
   7886         GenerateReturn(masm);
   7887         __ bind(&after_alloc_failure);
   7888         __ ffree();
   7889         __ jmp(&call_runtime);
   7890       }
   7891     }
   7892     case Token::MOD: {
   7893       // For MOD we go directly to runtime in the non-smi case.
   7894       break;
   7895     }
   7896     case Token::BIT_OR:
   7897     case Token::BIT_AND:
   7898     case Token::BIT_XOR:
   7899     case Token::SAR:
   7900     case Token::SHL:
   7901     case Token::SHR: {
   7902       Label non_smi_result;
   7903       FloatingPointHelper::LoadAsIntegers(masm, use_sse3_, &call_runtime);
   7904       switch (op_) {
   7905         case Token::BIT_OR:  __ or_(eax, Operand(ecx)); break;
   7906         case Token::BIT_AND: __ and_(eax, Operand(ecx)); break;
   7907         case Token::BIT_XOR: __ xor_(eax, Operand(ecx)); break;
   7908         case Token::SAR: __ sar_cl(eax); break;
   7909         case Token::SHL: __ shl_cl(eax); break;
   7910         case Token::SHR: __ shr_cl(eax); break;
   7911         default: UNREACHABLE();
   7912       }
   7913       if (op_ == Token::SHR) {
   7914         // Check if result is non-negative and fits in a smi.
   7915         __ test(eax, Immediate(0xc0000000));
   7916         __ j(not_zero, &call_runtime);
   7917       } else {
   7918         // Check if result fits in a smi.
   7919         __ cmp(eax, 0xc0000000);
   7920         __ j(negative, &non_smi_result);
   7921       }
   7922       // Tag smi result and return.
   7923       __ SmiTag(eax);
   7924       GenerateReturn(masm);
   7925 
   7926       // All ops except SHR return a signed int32 that we load in a HeapNumber.
   7927       if (op_ != Token::SHR) {
   7928         __ bind(&non_smi_result);
   7929         // Allocate a heap number if needed.
   7930         __ mov(ebx, Operand(eax));  // ebx: result
   7931         Label skip_allocation;
   7932         switch (mode_) {
   7933           case OVERWRITE_LEFT:
   7934           case OVERWRITE_RIGHT:
   7935             // If the operand was an object, we skip the
   7936             // allocation of a heap number.
   7937             __ mov(eax, Operand(esp, mode_ == OVERWRITE_RIGHT ?
   7938                                 1 * kPointerSize : 2 * kPointerSize));
   7939             __ test(eax, Immediate(kSmiTagMask));
   7940             __ j(not_zero, &skip_allocation, not_taken);
   7941             // Fall through!
   7942           case NO_OVERWRITE:
   7943             __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
   7944             __ bind(&skip_allocation);
   7945             break;
   7946           default: UNREACHABLE();
   7947         }
   7948         // Store the result in the HeapNumber and return.
   7949         if (CpuFeatures::IsSupported(SSE2)) {
   7950           CpuFeatures::Scope use_sse2(SSE2);
   7951           __ cvtsi2sd(xmm0, Operand(ebx));
   7952           __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
   7953         } else {
   7954           __ mov(Operand(esp, 1 * kPointerSize), ebx);
   7955           __ fild_s(Operand(esp, 1 * kPointerSize));
   7956           __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
   7957         }
   7958         GenerateReturn(masm);
   7959       }
   7960       break;
   7961     }
   7962     default: UNREACHABLE(); break;
   7963   }
   7964 
   7965   // If all else fails, use the runtime system to get the correct
   7966   // result. If arguments was passed in registers now place them on the
   7967   // stack in the correct order below the return address.
   7968   __ bind(&call_runtime);
   7969   if (HasArgsInRegisters()) {
   7970     __ pop(ecx);
   7971     if (HasArgsReversed()) {
   7972       __ push(eax);
   7973       __ push(edx);
   7974     } else {
   7975       __ push(edx);
   7976       __ push(eax);
   7977     }
   7978     __ push(ecx);
   7979   }
   7980   switch (op_) {
   7981     case Token::ADD: {
   7982       // Test for string arguments before calling runtime.
   7983       Label not_strings, not_string1, string1, string1_smi2;
   7984       Result answer;
   7985       __ test(edx, Immediate(kSmiTagMask));
   7986       __ j(zero, &not_string1);
   7987       __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ecx);
   7988       __ j(above_equal, &not_string1);
   7989 
   7990       // First argument is a string, test second.
   7991       __ test(eax, Immediate(kSmiTagMask));
   7992       __ j(zero, &string1_smi2);
   7993       __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
   7994       __ j(above_equal, &string1);
   7995 
   7996       // First and second argument are strings. Jump to the string add stub.
   7997       StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
   7998       __ TailCallStub(&string_add_stub);
   7999 
   8000       __ bind(&string1_smi2);
   8001       // First argument is a string, second is a smi. Try to lookup the number
   8002       // string for the smi in the number string cache.
   8003       NumberToStringStub::GenerateLookupNumberStringCache(
   8004           masm, eax, edi, ebx, ecx, true, &string1);
   8005 
   8006       // Call the string add stub to make the result.
   8007       __ EnterInternalFrame();
   8008       __ push(edx);  // Original first argument.
   8009       __ push(edi);  // Number to string result for second argument.
   8010       __ CallStub(&string_add_stub);
   8011       __ LeaveInternalFrame();
   8012       __ ret(2 * kPointerSize);
   8013 
   8014       __ bind(&string1);
   8015       __ InvokeBuiltin(
   8016           HasArgsReversed() ?
   8017               Builtins::STRING_ADD_RIGHT :
   8018               Builtins::STRING_ADD_LEFT,
   8019           JUMP_FUNCTION);
   8020 
   8021       // First argument was not a string, test second.
   8022       __ bind(&not_string1);
   8023       __ test(eax, Immediate(kSmiTagMask));
   8024       __ j(zero, &not_strings);
   8025       __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
   8026       __ j(above_equal, &not_strings);
   8027 
   8028       // Only second argument is a string.
   8029       __ InvokeBuiltin(
   8030           HasArgsReversed() ?
   8031               Builtins::STRING_ADD_LEFT :
   8032               Builtins::STRING_ADD_RIGHT,
   8033           JUMP_FUNCTION);
   8034 
   8035       __ bind(&not_strings);
   8036       // Neither argument is a string.
   8037       __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
   8038       break;
   8039     }
   8040     case Token::SUB:
   8041       __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
   8042       break;
   8043     case Token::MUL:
   8044       __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
   8045       break;
   8046     case Token::DIV:
   8047       __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
   8048       break;
   8049     case Token::MOD:
   8050       __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
   8051       break;
   8052     case Token::BIT_OR:
   8053       __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
   8054       break;
   8055     case Token::BIT_AND:
   8056       __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION);
   8057       break;
   8058     case Token::BIT_XOR:
   8059       __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION);
   8060       break;
   8061     case Token::SAR:
   8062       __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION);
   8063       break;
   8064     case Token::SHL:
   8065       __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION);
   8066       break;
   8067     case Token::SHR:
   8068       __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
   8069       break;
   8070     default:
   8071       UNREACHABLE();
   8072   }
   8073 }
   8074 
   8075 
   8076 void GenericBinaryOpStub::GenerateHeapResultAllocation(MacroAssembler* masm,
   8077                                                        Label* alloc_failure) {
   8078   Label skip_allocation;
   8079   OverwriteMode mode = mode_;
   8080   if (HasArgsReversed()) {
   8081     if (mode == OVERWRITE_RIGHT) {
   8082       mode = OVERWRITE_LEFT;
   8083     } else if (mode == OVERWRITE_LEFT) {
   8084       mode = OVERWRITE_RIGHT;
   8085     }
   8086   }
   8087   switch (mode) {
   8088     case OVERWRITE_LEFT: {
   8089       // If the argument in edx is already an object, we skip the
   8090       // allocation of a heap number.
   8091       __ test(edx, Immediate(kSmiTagMask));
   8092       __ j(not_zero, &skip_allocation, not_taken);
   8093       // Allocate a heap number for the result. Keep eax and edx intact
   8094       // for the possible runtime call.
   8095       __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure);
   8096       // Now edx can be overwritten losing one of the arguments as we are
   8097       // now done and will not need it any more.
   8098       __ mov(edx, Operand(ebx));
   8099       __ bind(&skip_allocation);
   8100       // Use object in edx as a result holder
   8101       __ mov(eax, Operand(edx));
   8102       break;
   8103     }
   8104     case OVERWRITE_RIGHT:
   8105       // If the argument in eax is already an object, we skip the
   8106       // allocation of a heap number.
   8107       __ test(eax, Immediate(kSmiTagMask));
   8108       __ j(not_zero, &skip_allocation, not_taken);
   8109       // Fall through!
   8110     case NO_OVERWRITE:
   8111       // Allocate a heap number for the result. Keep eax and edx intact
   8112       // for the possible runtime call.
   8113       __ AllocateHeapNumber(ebx, ecx, no_reg, alloc_failure);
   8114       // Now eax can be overwritten losing one of the arguments as we are
   8115       // now done and will not need it any more.
   8116       __ mov(eax, ebx);
   8117       __ bind(&skip_allocation);
   8118       break;
   8119     default: UNREACHABLE();
   8120   }
   8121 }
   8122 
   8123 
   8124 void GenericBinaryOpStub::GenerateLoadArguments(MacroAssembler* masm) {
   8125   // If arguments are not passed in registers read them from the stack.
   8126   if (!HasArgsInRegisters()) {
   8127     __ mov(eax, Operand(esp, 1 * kPointerSize));
   8128     __ mov(edx, Operand(esp, 2 * kPointerSize));
   8129   }
   8130 }
   8131 
   8132 
   8133 void GenericBinaryOpStub::GenerateReturn(MacroAssembler* masm) {
   8134   // If arguments are not passed in registers remove them from the stack before
   8135   // returning.
   8136   if (!HasArgsInRegisters()) {
   8137     __ ret(2 * kPointerSize);  // Remove both operands
   8138   } else {
   8139     __ ret(0);
   8140   }
   8141 }
   8142 
   8143 
   8144 void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   8145   // Input on stack:
   8146   // esp[4]: argument (should be number).
   8147   // esp[0]: return address.
   8148   // Test that eax is a number.
   8149   Label runtime_call;
   8150   Label runtime_call_clear_stack;
   8151   Label input_not_smi;
   8152   Label loaded;
   8153   __ mov(eax, Operand(esp, kPointerSize));
   8154   __ test(eax, Immediate(kSmiTagMask));
   8155   __ j(not_zero, &input_not_smi);
   8156   // Input is a smi. Untag and load it onto the FPU stack.
   8157   // Then load the low and high words of the double into ebx, edx.
   8158   ASSERT_EQ(1, kSmiTagSize);
   8159   __ sar(eax, 1);
   8160   __ sub(Operand(esp), Immediate(2 * kPointerSize));
   8161   __ mov(Operand(esp, 0), eax);
   8162   __ fild_s(Operand(esp, 0));
   8163   __ fst_d(Operand(esp, 0));
   8164   __ pop(edx);
   8165   __ pop(ebx);
   8166   __ jmp(&loaded);
   8167   __ bind(&input_not_smi);
   8168   // Check if input is a HeapNumber.
   8169   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   8170   __ cmp(Operand(ebx), Immediate(Factory::heap_number_map()));
   8171   __ j(not_equal, &runtime_call);
   8172   // Input is a HeapNumber. Push it on the FPU stack and load its
   8173   // low and high words into ebx, edx.
   8174   __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
   8175   __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
   8176   __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
   8177 
   8178   __ bind(&loaded);
   8179   // ST[0] == double value
   8180   // ebx = low 32 bits of double value
   8181   // edx = high 32 bits of double value
   8182   // Compute hash:
   8183   //   h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
   8184   __ mov(ecx, ebx);
   8185   __ xor_(ecx, Operand(edx));
   8186   __ mov(eax, ecx);
   8187   __ sar(eax, 16);
   8188   __ xor_(ecx, Operand(eax));
   8189   __ mov(eax, ecx);
   8190   __ sar(eax, 8);
   8191   __ xor_(ecx, Operand(eax));
   8192   ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize));
   8193   __ and_(Operand(ecx), Immediate(TranscendentalCache::kCacheSize - 1));
   8194   // ST[0] == double value.
   8195   // ebx = low 32 bits of double value.
   8196   // edx = high 32 bits of double value.
   8197   // ecx = TranscendentalCache::hash(double value).
   8198   __ mov(eax,
   8199          Immediate(ExternalReference::transcendental_cache_array_address()));
   8200   // Eax points to cache array.
   8201   __ mov(eax, Operand(eax, type_ * sizeof(TranscendentalCache::caches_[0])));
   8202   // Eax points to the cache for the type type_.
   8203   // If NULL, the cache hasn't been initialized yet, so go through runtime.
   8204   __ test(eax, Operand(eax));
   8205   __ j(zero, &runtime_call_clear_stack);
   8206 #ifdef DEBUG
   8207   // Check that the layout of cache elements match expectations.
   8208   {  // NOLINT - doesn't like a single brace on a line.
   8209     TranscendentalCache::Element test_elem[2];
   8210     char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
   8211     char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
   8212     char* elem_in0  = reinterpret_cast<char*>(&(test_elem[0].in[0]));
   8213     char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
   8214     char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
   8215     CHECK_EQ(12, elem2_start - elem_start);  // Two uint_32's and a pointer.
   8216     CHECK_EQ(0, elem_in0 - elem_start);
   8217     CHECK_EQ(kIntSize, elem_in1 - elem_start);
   8218     CHECK_EQ(2 * kIntSize, elem_out - elem_start);
   8219   }
   8220 #endif
   8221   // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12].
   8222   __ lea(ecx, Operand(ecx, ecx, times_2, 0));
   8223   __ lea(ecx, Operand(eax, ecx, times_4, 0));
   8224   // Check if cache matches: Double value is stored in uint32_t[2] array.
   8225   Label cache_miss;
   8226   __ cmp(ebx, Operand(ecx, 0));
   8227   __ j(not_equal, &cache_miss);
   8228   __ cmp(edx, Operand(ecx, kIntSize));
   8229   __ j(not_equal, &cache_miss);
   8230   // Cache hit!
   8231   __ mov(eax, Operand(ecx, 2 * kIntSize));
   8232   __ fstp(0);
   8233   __ ret(kPointerSize);
   8234 
   8235   __ bind(&cache_miss);
   8236   // Update cache with new value.
   8237   // We are short on registers, so use no_reg as scratch.
   8238   // This gives slightly larger code.
   8239   __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
   8240   GenerateOperation(masm);
   8241   __ mov(Operand(ecx, 0), ebx);
   8242   __ mov(Operand(ecx, kIntSize), edx);
   8243   __ mov(Operand(ecx, 2 * kIntSize), eax);
   8244   __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
   8245   __ ret(kPointerSize);
   8246 
   8247   __ bind(&runtime_call_clear_stack);
   8248   __ fstp(0);
   8249   __ bind(&runtime_call);
   8250   __ TailCallRuntime(ExternalReference(RuntimeFunction()), 1, 1);
   8251 }
   8252 
   8253 
   8254 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
   8255   switch (type_) {
   8256     // Add more cases when necessary.
   8257     case TranscendentalCache::SIN: return Runtime::kMath_sin;
   8258     case TranscendentalCache::COS: return Runtime::kMath_cos;
   8259     default:
   8260       UNIMPLEMENTED();
   8261       return Runtime::kAbort;
   8262   }
   8263 }
   8264 
   8265 
   8266 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
   8267   // Only free register is edi.
   8268   Label done;
   8269   ASSERT(type_ == TranscendentalCache::SIN ||
   8270          type_ == TranscendentalCache::COS);
   8271   // More transcendental types can be added later.
   8272 
   8273   // Both fsin and fcos require arguments in the range +/-2^63 and
   8274   // return NaN for infinities and NaN. They can share all code except
   8275   // the actual fsin/fcos operation.
   8276   Label in_range;
   8277   // If argument is outside the range -2^63..2^63, fsin/cos doesn't
   8278   // work. We must reduce it to the appropriate range.
   8279   __ mov(edi, edx);
   8280   __ and_(Operand(edi), Immediate(0x7ff00000));  // Exponent only.
   8281   int supported_exponent_limit =
   8282       (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift;
   8283   __ cmp(Operand(edi), Immediate(supported_exponent_limit));
   8284   __ j(below, &in_range, taken);
   8285   // Check for infinity and NaN. Both return NaN for sin.
   8286   __ cmp(Operand(edi), Immediate(0x7ff00000));
   8287   Label non_nan_result;
   8288   __ j(not_equal, &non_nan_result, taken);
   8289   // Input is +/-Infinity or NaN. Result is NaN.
   8290   __ fstp(0);
   8291   // NaN is represented by 0x7ff8000000000000.
   8292   __ push(Immediate(0x7ff80000));
   8293   __ push(Immediate(0));
   8294   __ fld_d(Operand(esp, 0));
   8295   __ add(Operand(esp), Immediate(2 * kPointerSize));
   8296   __ jmp(&done);
   8297 
   8298   __ bind(&non_nan_result);
   8299 
   8300   // Use fpmod to restrict argument to the range +/-2*PI.
   8301   __ mov(edi, eax);  // Save eax before using fnstsw_ax.
   8302   __ fldpi();
   8303   __ fadd(0);
   8304   __ fld(1);
   8305   // FPU Stack: input, 2*pi, input.
   8306   {
   8307     Label no_exceptions;
   8308     __ fwait();
   8309     __ fnstsw_ax();
   8310     // Clear if Illegal Operand or Zero Division exceptions are set.
   8311     __ test(Operand(eax), Immediate(5));
   8312     __ j(zero, &no_exceptions);
   8313     __ fnclex();
   8314     __ bind(&no_exceptions);
   8315   }
   8316 
   8317   // Compute st(0) % st(1)
   8318   {
   8319     Label partial_remainder_loop;
   8320     __ bind(&partial_remainder_loop);
   8321     __ fprem1();
   8322     __ fwait();
   8323     __ fnstsw_ax();
   8324     __ test(Operand(eax), Immediate(0x400 /* C2 */));
   8325     // If C2 is set, computation only has partial result. Loop to
   8326     // continue computation.
   8327     __ j(not_zero, &partial_remainder_loop);
   8328   }
   8329   // FPU Stack: input, 2*pi, input % 2*pi
   8330   __ fstp(2);
   8331   __ fstp(0);
   8332   __ mov(eax, edi);  // Restore eax (allocated HeapNumber pointer).
   8333 
   8334   // FPU Stack: input % 2*pi
   8335   __ bind(&in_range);
   8336   switch (type_) {
   8337     case TranscendentalCache::SIN:
   8338       __ fsin();
   8339       break;
   8340     case TranscendentalCache::COS:
   8341       __ fcos();
   8342       break;
   8343     default:
   8344       UNREACHABLE();
   8345   }
   8346   __ bind(&done);
   8347 }
   8348 
   8349 
   8350 // Get the integer part of a heap number.  Surprisingly, all this bit twiddling
   8351 // is faster than using the built-in instructions on floating point registers.
   8352 // Trashes edi and ebx.  Dest is ecx.  Source cannot be ecx or one of the
   8353 // trashed registers.
   8354 void IntegerConvert(MacroAssembler* masm,
   8355                     Register source,
   8356                     bool use_sse3,
   8357                     Label* conversion_failure) {
   8358   ASSERT(!source.is(ecx) && !source.is(edi) && !source.is(ebx));
   8359   Label done, right_exponent, normal_exponent;
   8360   Register scratch = ebx;
   8361   Register scratch2 = edi;
   8362   // Get exponent word.
   8363   __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset));
   8364   // Get exponent alone in scratch2.
   8365   __ mov(scratch2, scratch);
   8366   __ and_(scratch2, HeapNumber::kExponentMask);
   8367   if (use_sse3) {
   8368     CpuFeatures::Scope scope(SSE3);
   8369     // Check whether the exponent is too big for a 64 bit signed integer.
   8370     static const uint32_t kTooBigExponent =
   8371         (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
   8372     __ cmp(Operand(scratch2), Immediate(kTooBigExponent));
   8373     __ j(greater_equal, conversion_failure);
   8374     // Load x87 register with heap number.
   8375     __ fld_d(FieldOperand(source, HeapNumber::kValueOffset));
   8376     // Reserve space for 64 bit answer.
   8377     __ sub(Operand(esp), Immediate(sizeof(uint64_t)));  // Nolint.
   8378     // Do conversion, which cannot fail because we checked the exponent.
   8379     __ fisttp_d(Operand(esp, 0));
   8380     __ mov(ecx, Operand(esp, 0));  // Load low word of answer into ecx.
   8381     __ add(Operand(esp), Immediate(sizeof(uint64_t)));  // Nolint.
   8382   } else {
   8383     // Load ecx with zero.  We use this either for the final shift or
   8384     // for the answer.
   8385     __ xor_(ecx, Operand(ecx));
   8386     // Check whether the exponent matches a 32 bit signed int that cannot be
   8387     // represented by a Smi.  A non-smi 32 bit integer is 1.xxx * 2^30 so the
   8388     // exponent is 30 (biased).  This is the exponent that we are fastest at and
   8389     // also the highest exponent we can handle here.
   8390     const uint32_t non_smi_exponent =
   8391         (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
   8392     __ cmp(Operand(scratch2), Immediate(non_smi_exponent));
   8393     // If we have a match of the int32-but-not-Smi exponent then skip some
   8394     // logic.
   8395     __ j(equal, &right_exponent);
   8396     // If the exponent is higher than that then go to slow case.  This catches
   8397     // numbers that don't fit in a signed int32, infinities and NaNs.
   8398     __ j(less, &normal_exponent);
   8399 
   8400     {
   8401       // Handle a big exponent.  The only reason we have this code is that the
   8402       // >>> operator has a tendency to generate numbers with an exponent of 31.
   8403       const uint32_t big_non_smi_exponent =
   8404           (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift;
   8405       __ cmp(Operand(scratch2), Immediate(big_non_smi_exponent));
   8406       __ j(not_equal, conversion_failure);
   8407       // We have the big exponent, typically from >>>.  This means the number is
   8408       // in the range 2^31 to 2^32 - 1.  Get the top bits of the mantissa.
   8409       __ mov(scratch2, scratch);
   8410       __ and_(scratch2, HeapNumber::kMantissaMask);
   8411       // Put back the implicit 1.
   8412       __ or_(scratch2, 1 << HeapNumber::kExponentShift);
   8413       // Shift up the mantissa bits to take up the space the exponent used to
   8414       // take. We just orred in the implicit bit so that took care of one and
   8415       // we want to use the full unsigned range so we subtract 1 bit from the
   8416       // shift distance.
   8417       const int big_shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1;
   8418       __ shl(scratch2, big_shift_distance);
   8419       // Get the second half of the double.
   8420       __ mov(ecx, FieldOperand(source, HeapNumber::kMantissaOffset));
   8421       // Shift down 21 bits to get the most significant 11 bits or the low
   8422       // mantissa word.
   8423       __ shr(ecx, 32 - big_shift_distance);
   8424       __ or_(ecx, Operand(scratch2));
   8425       // We have the answer in ecx, but we may need to negate it.
   8426       __ test(scratch, Operand(scratch));
   8427       __ j(positive, &done);
   8428       __ neg(ecx);
   8429       __ jmp(&done);
   8430     }
   8431 
   8432     __ bind(&normal_exponent);
   8433     // Exponent word in scratch, exponent part of exponent word in scratch2.
   8434     // Zero in ecx.
   8435     // We know the exponent is smaller than 30 (biased).  If it is less than
   8436     // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie
   8437     // it rounds to zero.
   8438     const uint32_t zero_exponent =
   8439         (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift;
   8440     __ sub(Operand(scratch2), Immediate(zero_exponent));
   8441     // ecx already has a Smi zero.
   8442     __ j(less, &done);
   8443 
   8444     // We have a shifted exponent between 0 and 30 in scratch2.
   8445     __ shr(scratch2, HeapNumber::kExponentShift);
   8446     __ mov(ecx, Immediate(30));
   8447     __ sub(ecx, Operand(scratch2));
   8448 
   8449     __ bind(&right_exponent);
   8450     // Here ecx is the shift, scratch is the exponent word.
   8451     // Get the top bits of the mantissa.
   8452     __ and_(scratch, HeapNumber::kMantissaMask);
   8453     // Put back the implicit 1.
   8454     __ or_(scratch, 1 << HeapNumber::kExponentShift);
   8455     // Shift up the mantissa bits to take up the space the exponent used to
   8456     // take. We have kExponentShift + 1 significant bits int he low end of the
   8457     // word.  Shift them to the top bits.
   8458     const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
   8459     __ shl(scratch, shift_distance);
   8460     // Get the second half of the double. For some exponents we don't
   8461     // actually need this because the bits get shifted out again, but
   8462     // it's probably slower to test than just to do it.
   8463     __ mov(scratch2, FieldOperand(source, HeapNumber::kMantissaOffset));
   8464     // Shift down 22 bits to get the most significant 10 bits or the low
   8465     // mantissa word.
   8466     __ shr(scratch2, 32 - shift_distance);
   8467     __ or_(scratch2, Operand(scratch));
   8468     // Move down according to the exponent.
   8469     __ shr_cl(scratch2);
   8470     // Now the unsigned answer is in scratch2.  We need to move it to ecx and
   8471     // we may need to fix the sign.
   8472     Label negative;
   8473     __ xor_(ecx, Operand(ecx));
   8474     __ cmp(ecx, FieldOperand(source, HeapNumber::kExponentOffset));
   8475     __ j(greater, &negative);
   8476     __ mov(ecx, scratch2);
   8477     __ jmp(&done);
   8478     __ bind(&negative);
   8479     __ sub(ecx, Operand(scratch2));
   8480     __ bind(&done);
   8481   }
   8482 }
   8483 
   8484 
   8485 // Input: edx, eax are the left and right objects of a bit op.
   8486 // Output: eax, ecx are left and right integers for a bit op.
   8487 void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
   8488                                          bool use_sse3,
   8489                                          Label* conversion_failure) {
   8490   // Check float operands.
   8491   Label arg1_is_object, check_undefined_arg1;
   8492   Label arg2_is_object, check_undefined_arg2;
   8493   Label load_arg2, done;
   8494 
   8495   __ test(edx, Immediate(kSmiTagMask));
   8496   __ j(not_zero, &arg1_is_object);
   8497   __ SmiUntag(edx);
   8498   __ jmp(&load_arg2);
   8499 
   8500   // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
   8501   __ bind(&check_undefined_arg1);
   8502   __ cmp(edx, Factory::undefined_value());
   8503   __ j(not_equal, conversion_failure);
   8504   __ mov(edx, Immediate(0));
   8505   __ jmp(&load_arg2);
   8506 
   8507   __ bind(&arg1_is_object);
   8508   __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
   8509   __ cmp(ebx, Factory::heap_number_map());
   8510   __ j(not_equal, &check_undefined_arg1);
   8511   // Get the untagged integer version of the edx heap number in ecx.
   8512   IntegerConvert(masm, edx, use_sse3, conversion_failure);
   8513   __ mov(edx, ecx);
   8514 
   8515   // Here edx has the untagged integer, eax has a Smi or a heap number.
   8516   __ bind(&load_arg2);
   8517   // Test if arg2 is a Smi.
   8518   __ test(eax, Immediate(kSmiTagMask));
   8519   __ j(not_zero, &arg2_is_object);
   8520   __ SmiUntag(eax);
   8521   __ mov(ecx, eax);
   8522   __ jmp(&done);
   8523 
   8524   // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
   8525   __ bind(&check_undefined_arg2);
   8526   __ cmp(eax, Factory::undefined_value());
   8527   __ j(not_equal, conversion_failure);
   8528   __ mov(ecx, Immediate(0));
   8529   __ jmp(&done);
   8530 
   8531   __ bind(&arg2_is_object);
   8532   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   8533   __ cmp(ebx, Factory::heap_number_map());
   8534   __ j(not_equal, &check_undefined_arg2);
   8535   // Get the untagged integer version of the eax heap number in ecx.
   8536   IntegerConvert(masm, eax, use_sse3, conversion_failure);
   8537   __ bind(&done);
   8538   __ mov(eax, edx);
   8539 }
   8540 
   8541 
   8542 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
   8543                                            Register number) {
   8544   Label load_smi, done;
   8545 
   8546   __ test(number, Immediate(kSmiTagMask));
   8547   __ j(zero, &load_smi, not_taken);
   8548   __ fld_d(FieldOperand(number, HeapNumber::kValueOffset));
   8549   __ jmp(&done);
   8550 
   8551   __ bind(&load_smi);
   8552   __ SmiUntag(number);
   8553   __ push(number);
   8554   __ fild_s(Operand(esp, 0));
   8555   __ pop(number);
   8556 
   8557   __ bind(&done);
   8558 }
   8559 
   8560 
   8561 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm) {
   8562   Label load_smi_edx, load_eax, load_smi_eax, done;
   8563   // Load operand in edx into xmm0.
   8564   __ test(edx, Immediate(kSmiTagMask));
   8565   __ j(zero, &load_smi_edx, not_taken);  // Argument in edx is a smi.
   8566   __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
   8567 
   8568   __ bind(&load_eax);
   8569   // Load operand in eax into xmm1.
   8570   __ test(eax, Immediate(kSmiTagMask));
   8571   __ j(zero, &load_smi_eax, not_taken);  // Argument in eax is a smi.
   8572   __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
   8573   __ jmp(&done);
   8574 
   8575   __ bind(&load_smi_edx);
   8576   __ SmiUntag(edx);  // Untag smi before converting to float.
   8577   __ cvtsi2sd(xmm0, Operand(edx));
   8578   __ SmiTag(edx);  // Retag smi for heap number overwriting test.
   8579   __ jmp(&load_eax);
   8580 
   8581   __ bind(&load_smi_eax);
   8582   __ SmiUntag(eax);  // Untag smi before converting to float.
   8583   __ cvtsi2sd(xmm1, Operand(eax));
   8584   __ SmiTag(eax);  // Retag smi for heap number overwriting test.
   8585 
   8586   __ bind(&done);
   8587 }
   8588 
   8589 
   8590 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm,
   8591                                            Label* not_numbers) {
   8592   Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
   8593   // Load operand in edx into xmm0, or branch to not_numbers.
   8594   __ test(edx, Immediate(kSmiTagMask));
   8595   __ j(zero, &load_smi_edx, not_taken);  // Argument in edx is a smi.
   8596   __ cmp(FieldOperand(edx, HeapObject::kMapOffset), Factory::heap_number_map());
   8597   __ j(not_equal, not_numbers);  // Argument in edx is not a number.
   8598   __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
   8599   __ bind(&load_eax);
   8600   // Load operand in eax into xmm1, or branch to not_numbers.
   8601   __ test(eax, Immediate(kSmiTagMask));
   8602   __ j(zero, &load_smi_eax, not_taken);  // Argument in eax is a smi.
   8603   __ cmp(FieldOperand(eax, HeapObject::kMapOffset), Factory::heap_number_map());
   8604   __ j(equal, &load_float_eax);
   8605   __ jmp(not_numbers);  // Argument in eax is not a number.
   8606   __ bind(&load_smi_edx);
   8607   __ SmiUntag(edx);  // Untag smi before converting to float.
   8608   __ cvtsi2sd(xmm0, Operand(edx));
   8609   __ SmiTag(edx);  // Retag smi for heap number overwriting test.
   8610   __ jmp(&load_eax);
   8611   __ bind(&load_smi_eax);
   8612   __ SmiUntag(eax);  // Untag smi before converting to float.
   8613   __ cvtsi2sd(xmm1, Operand(eax));
   8614   __ SmiTag(eax);  // Retag smi for heap number overwriting test.
   8615   __ jmp(&done);
   8616   __ bind(&load_float_eax);
   8617   __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
   8618   __ bind(&done);
   8619 }
   8620 
   8621 
   8622 void FloatingPointHelper::LoadSSE2Smis(MacroAssembler* masm,
   8623                                        Register scratch) {
   8624   const Register left = edx;
   8625   const Register right = eax;
   8626   __ mov(scratch, left);
   8627   ASSERT(!scratch.is(right));  // We're about to clobber scratch.
   8628   __ SmiUntag(scratch);
   8629   __ cvtsi2sd(xmm0, Operand(scratch));
   8630 
   8631   __ mov(scratch, right);
   8632   __ SmiUntag(scratch);
   8633   __ cvtsi2sd(xmm1, Operand(scratch));
   8634 }
   8635 
   8636 
   8637 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
   8638                                             Register scratch,
   8639                                             ArgLocation arg_location) {
   8640   Label load_smi_1, load_smi_2, done_load_1, done;
   8641   if (arg_location == ARGS_IN_REGISTERS) {
   8642     __ mov(scratch, edx);
   8643   } else {
   8644     __ mov(scratch, Operand(esp, 2 * kPointerSize));
   8645   }
   8646   __ test(scratch, Immediate(kSmiTagMask));
   8647   __ j(zero, &load_smi_1, not_taken);
   8648   __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset));
   8649   __ bind(&done_load_1);
   8650 
   8651   if (arg_location == ARGS_IN_REGISTERS) {
   8652     __ mov(scratch, eax);
   8653   } else {
   8654     __ mov(scratch, Operand(esp, 1 * kPointerSize));
   8655   }
   8656   __ test(scratch, Immediate(kSmiTagMask));
   8657   __ j(zero, &load_smi_2, not_taken);
   8658   __ fld_d(FieldOperand(scratch, HeapNumber::kValueOffset));
   8659   __ jmp(&done);
   8660 
   8661   __ bind(&load_smi_1);
   8662   __ SmiUntag(scratch);
   8663   __ push(scratch);
   8664   __ fild_s(Operand(esp, 0));
   8665   __ pop(scratch);
   8666   __ jmp(&done_load_1);
   8667 
   8668   __ bind(&load_smi_2);
   8669   __ SmiUntag(scratch);
   8670   __ push(scratch);
   8671   __ fild_s(Operand(esp, 0));
   8672   __ pop(scratch);
   8673 
   8674   __ bind(&done);
   8675 }
   8676 
   8677 
   8678 void FloatingPointHelper::LoadFloatSmis(MacroAssembler* masm,
   8679                                         Register scratch) {
   8680   const Register left = edx;
   8681   const Register right = eax;
   8682   __ mov(scratch, left);
   8683   ASSERT(!scratch.is(right));  // We're about to clobber scratch.
   8684   __ SmiUntag(scratch);
   8685   __ push(scratch);
   8686   __ fild_s(Operand(esp, 0));
   8687 
   8688   __ mov(scratch, right);
   8689   __ SmiUntag(scratch);
   8690   __ mov(Operand(esp, 0), scratch);
   8691   __ fild_s(Operand(esp, 0));
   8692   __ pop(scratch);
   8693 }
   8694 
   8695 
   8696 void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
   8697                                              Label* non_float,
   8698                                              Register scratch) {
   8699   Label test_other, done;
   8700   // Test if both operands are floats or smi -> scratch=k_is_float;
   8701   // Otherwise scratch = k_not_float.
   8702   __ test(edx, Immediate(kSmiTagMask));
   8703   __ j(zero, &test_other, not_taken);  // argument in edx is OK
   8704   __ mov(scratch, FieldOperand(edx, HeapObject::kMapOffset));
   8705   __ cmp(scratch, Factory::heap_number_map());
   8706   __ j(not_equal, non_float);  // argument in edx is not a number -> NaN
   8707 
   8708   __ bind(&test_other);
   8709   __ test(eax, Immediate(kSmiTagMask));
   8710   __ j(zero, &done);  // argument in eax is OK
   8711   __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
   8712   __ cmp(scratch, Factory::heap_number_map());
   8713   __ j(not_equal, non_float);  // argument in eax is not a number -> NaN
   8714 
   8715   // Fall-through: Both operands are numbers.
   8716   __ bind(&done);
   8717 }
   8718 
   8719 
   8720 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
   8721   Label slow, done;
   8722 
   8723   if (op_ == Token::SUB) {
   8724     // Check whether the value is a smi.
   8725     Label try_float;
   8726     __ test(eax, Immediate(kSmiTagMask));
   8727     __ j(not_zero, &try_float, not_taken);
   8728 
   8729     // Go slow case if the value of the expression is zero
   8730     // to make sure that we switch between 0 and -0.
   8731     __ test(eax, Operand(eax));
   8732     __ j(zero, &slow, not_taken);
   8733 
   8734     // The value of the expression is a smi that is not zero.  Try
   8735     // optimistic subtraction '0 - value'.
   8736     Label undo;
   8737     __ mov(edx, Operand(eax));
   8738     __ Set(eax, Immediate(0));
   8739     __ sub(eax, Operand(edx));
   8740     __ j(overflow, &undo, not_taken);
   8741 
   8742     // If result is a smi we are done.
   8743     __ test(eax, Immediate(kSmiTagMask));
   8744     __ j(zero, &done, taken);
   8745 
   8746     // Restore eax and go slow case.
   8747     __ bind(&undo);
   8748     __ mov(eax, Operand(edx));
   8749     __ jmp(&slow);
   8750 
   8751     // Try floating point case.
   8752     __ bind(&try_float);
   8753     __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
   8754     __ cmp(edx, Factory::heap_number_map());
   8755     __ j(not_equal, &slow);
   8756     if (overwrite_) {
   8757       __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
   8758       __ xor_(edx, HeapNumber::kSignMask);  // Flip sign.
   8759       __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx);
   8760     } else {
   8761       __ mov(edx, Operand(eax));
   8762       // edx: operand
   8763       __ AllocateHeapNumber(eax, ebx, ecx, &undo);
   8764       // eax: allocated 'empty' number
   8765       __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
   8766       __ xor_(ecx, HeapNumber::kSignMask);  // Flip sign.
   8767       __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ecx);
   8768       __ mov(ecx, FieldOperand(edx, HeapNumber::kMantissaOffset));
   8769       __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
   8770     }
   8771   } else if (op_ == Token::BIT_NOT) {
   8772     // Check if the operand is a heap number.
   8773     __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
   8774     __ cmp(edx, Factory::heap_number_map());
   8775     __ j(not_equal, &slow, not_taken);
   8776 
   8777     // Convert the heap number in eax to an untagged integer in ecx.
   8778     IntegerConvert(masm, eax, CpuFeatures::IsSupported(SSE3), &slow);
   8779 
   8780     // Do the bitwise operation and check if the result fits in a smi.
   8781     Label try_float;
   8782     __ not_(ecx);
   8783     __ cmp(ecx, 0xc0000000);
   8784     __ j(sign, &try_float, not_taken);
   8785 
   8786     // Tag the result as a smi and we're done.
   8787     ASSERT(kSmiTagSize == 1);
   8788     __ lea(eax, Operand(ecx, times_2, kSmiTag));
   8789     __ jmp(&done);
   8790 
   8791     // Try to store the result in a heap number.
   8792     __ bind(&try_float);
   8793     if (!overwrite_) {
   8794       // Allocate a fresh heap number, but don't overwrite eax until
   8795       // we're sure we can do it without going through the slow case
   8796       // that needs the value in eax.
   8797       __ AllocateHeapNumber(ebx, edx, edi, &slow);
   8798       __ mov(eax, Operand(ebx));
   8799     }
   8800     if (CpuFeatures::IsSupported(SSE2)) {
   8801       CpuFeatures::Scope use_sse2(SSE2);
   8802       __ cvtsi2sd(xmm0, Operand(ecx));
   8803       __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
   8804     } else {
   8805       __ push(ecx);
   8806       __ fild_s(Operand(esp, 0));
   8807       __ pop(ecx);
   8808       __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
   8809     }
   8810   } else {
   8811     UNIMPLEMENTED();
   8812   }
   8813 
   8814   // Return from the stub.
   8815   __ bind(&done);
   8816   __ StubReturn(1);
   8817 
   8818   // Handle the slow case by jumping to the JavaScript builtin.
   8819   __ bind(&slow);
   8820   __ pop(ecx);  // pop return address.
   8821   __ push(eax);
   8822   __ push(ecx);  // push return address
   8823   switch (op_) {
   8824     case Token::SUB:
   8825       __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
   8826       break;
   8827     case Token::BIT_NOT:
   8828       __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION);
   8829       break;
   8830     default:
   8831       UNREACHABLE();
   8832   }
   8833 }
   8834 
   8835 
   8836 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
   8837   // Check if the calling frame is an arguments adaptor frame.
   8838   __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
   8839   __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
   8840   __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   8841 
   8842   // Arguments adaptor case: Read the arguments length from the
   8843   // adaptor frame and return it.
   8844   // Otherwise nothing to do: The number of formal parameters has already been
   8845   // passed in register eax by calling function. Just return it.
   8846   if (CpuFeatures::IsSupported(CMOV)) {
   8847     CpuFeatures::Scope use_cmov(CMOV);
   8848     __ cmov(equal, eax,
   8849             Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   8850   } else {
   8851     Label exit;
   8852     __ j(not_equal, &exit);
   8853     __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   8854     __ bind(&exit);
   8855   }
   8856   __ ret(0);
   8857 }
   8858 
   8859 
   8860 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   8861   // The key is in edx and the parameter count is in eax.
   8862 
   8863   // The displacement is used for skipping the frame pointer on the
   8864   // stack. It is the offset of the last parameter (if any) relative
   8865   // to the frame pointer.
   8866   static const int kDisplacement = 1 * kPointerSize;
   8867 
   8868   // Check that the key is a smi.
   8869   Label slow;
   8870   __ test(edx, Immediate(kSmiTagMask));
   8871   __ j(not_zero, &slow, not_taken);
   8872 
   8873   // Check if the calling frame is an arguments adaptor frame.
   8874   Label adaptor;
   8875   __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
   8876   __ mov(ecx, Operand(ebx, StandardFrameConstants::kContextOffset));
   8877   __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   8878   __ j(equal, &adaptor);
   8879 
   8880   // Check index against formal parameters count limit passed in
   8881   // through register eax. Use unsigned comparison to get negative
   8882   // check for free.
   8883   __ cmp(edx, Operand(eax));
   8884   __ j(above_equal, &slow, not_taken);
   8885 
   8886   // Read the argument from the stack and return it.
   8887   ASSERT(kSmiTagSize == 1 && kSmiTag == 0);  // shifting code depends on this
   8888   __ lea(ebx, Operand(ebp, eax, times_2, 0));
   8889   __ neg(edx);
   8890   __ mov(eax, Operand(ebx, edx, times_2, kDisplacement));
   8891   __ ret(0);
   8892 
   8893   // Arguments adaptor case: Check index against actual arguments
   8894   // limit found in the arguments adaptor frame. Use unsigned
   8895   // comparison to get negative check for free.
   8896   __ bind(&adaptor);
   8897   __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   8898   __ cmp(edx, Operand(ecx));
   8899   __ j(above_equal, &slow, not_taken);
   8900 
   8901   // Read the argument from the stack and return it.
   8902   ASSERT(kSmiTagSize == 1 && kSmiTag == 0);  // shifting code depends on this
   8903   __ lea(ebx, Operand(ebx, ecx, times_2, 0));
   8904   __ neg(edx);
   8905   __ mov(eax, Operand(ebx, edx, times_2, kDisplacement));
   8906   __ ret(0);
   8907 
   8908   // Slow-case: Handle non-smi or out-of-bounds access to arguments
   8909   // by calling the runtime system.
   8910   __ bind(&slow);
   8911   __ pop(ebx);  // Return address.
   8912   __ push(edx);
   8913   __ push(ebx);
   8914   __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
   8915 }
   8916 
   8917 
   8918 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
   8919   // esp[0] : return address
   8920   // esp[4] : number of parameters
   8921   // esp[8] : receiver displacement
   8922   // esp[16] : function
   8923 
   8924   // The displacement is used for skipping the return address and the
   8925   // frame pointer on the stack. It is the offset of the last
   8926   // parameter (if any) relative to the frame pointer.
   8927   static const int kDisplacement = 2 * kPointerSize;
   8928 
   8929   // Check if the calling frame is an arguments adaptor frame.
   8930   Label adaptor_frame, try_allocate, runtime;
   8931   __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
   8932   __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
   8933   __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
   8934   __ j(equal, &adaptor_frame);
   8935 
   8936   // Get the length from the frame.
   8937   __ mov(ecx, Operand(esp, 1 * kPointerSize));
   8938   __ jmp(&try_allocate);
   8939 
   8940   // Patch the arguments.length and the parameters pointer.
   8941   __ bind(&adaptor_frame);
   8942   __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
   8943   __ mov(Operand(esp, 1 * kPointerSize), ecx);
   8944   __ lea(edx, Operand(edx, ecx, times_2, kDisplacement));
   8945   __ mov(Operand(esp, 2 * kPointerSize), edx);
   8946 
   8947   // Try the new space allocation. Start out with computing the size of
   8948   // the arguments object and the elements array.
   8949   Label add_arguments_object;
   8950   __ bind(&try_allocate);
   8951   __ test(ecx, Operand(ecx));
   8952   __ j(zero, &add_arguments_object);
   8953   __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize));
   8954   __ bind(&add_arguments_object);
   8955   __ add(Operand(ecx), Immediate(Heap::kArgumentsObjectSize));
   8956 
   8957   // Do the allocation of both objects in one go.
   8958   __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
   8959 
   8960   // Get the arguments boilerplate from the current (global) context.
   8961   int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
   8962   __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
   8963   __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
   8964   __ mov(edi, Operand(edi, offset));
   8965 
   8966   // Copy the JS object part.
   8967   for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
   8968     __ mov(ebx, FieldOperand(edi, i));
   8969     __ mov(FieldOperand(eax, i), ebx);
   8970   }
   8971 
   8972   // Setup the callee in-object property.
   8973   ASSERT(Heap::arguments_callee_index == 0);
   8974   __ mov(ebx, Operand(esp, 3 * kPointerSize));
   8975   __ mov(FieldOperand(eax, JSObject::kHeaderSize), ebx);
   8976 
   8977   // Get the length (smi tagged) and set that as an in-object property too.
   8978   ASSERT(Heap::arguments_length_index == 1);
   8979   __ mov(ecx, Operand(esp, 1 * kPointerSize));
   8980   __ mov(FieldOperand(eax, JSObject::kHeaderSize + kPointerSize), ecx);
   8981 
   8982   // If there are no actual arguments, we're done.
   8983   Label done;
   8984   __ test(ecx, Operand(ecx));
   8985   __ j(zero, &done);
   8986 
   8987   // Get the parameters pointer from the stack and untag the length.
   8988   __ mov(edx, Operand(esp, 2 * kPointerSize));
   8989   __ SmiUntag(ecx);
   8990 
   8991   // Setup the elements pointer in the allocated arguments object and
   8992   // initialize the header in the elements fixed array.
   8993   __ lea(edi, Operand(eax, Heap::kArgumentsObjectSize));
   8994   __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
   8995   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
   8996          Immediate(Factory::fixed_array_map()));
   8997   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
   8998 
   8999   // Copy the fixed array slots.
   9000   Label loop;
   9001   __ bind(&loop);
   9002   __ mov(ebx, Operand(edx, -1 * kPointerSize));  // Skip receiver.
   9003   __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
   9004   __ add(Operand(edi), Immediate(kPointerSize));
   9005   __ sub(Operand(edx), Immediate(kPointerSize));
   9006   __ dec(ecx);
   9007   __ j(not_zero, &loop);
   9008 
   9009   // Return and remove the on-stack parameters.
   9010   __ bind(&done);
   9011   __ ret(3 * kPointerSize);
   9012 
   9013   // Do the runtime call to allocate the arguments object.
   9014   __ bind(&runtime);
   9015   __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
   9016 }
   9017 
   9018 
   9019 void RegExpExecStub::Generate(MacroAssembler* masm) {
   9020   // Just jump directly to runtime if native RegExp is not selected at compile
   9021   // time or if regexp entry in generated code is turned off runtime switch or
   9022   // at compilation.
   9023 #ifndef V8_NATIVE_REGEXP
   9024   __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
   9025 #else  // V8_NATIVE_REGEXP
   9026   if (!FLAG_regexp_entry_native) {
   9027     __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
   9028     return;
   9029   }
   9030 
   9031   // Stack frame on entry.
   9032   //  esp[0]: return address
   9033   //  esp[4]: last_match_info (expected JSArray)
   9034   //  esp[8]: previous index
   9035   //  esp[12]: subject string
   9036   //  esp[16]: JSRegExp object
   9037 
   9038   static const int kLastMatchInfoOffset = 1 * kPointerSize;
   9039   static const int kPreviousIndexOffset = 2 * kPointerSize;
   9040   static const int kSubjectOffset = 3 * kPointerSize;
   9041   static const int kJSRegExpOffset = 4 * kPointerSize;
   9042 
   9043   Label runtime, invoke_regexp;
   9044 
   9045   // Ensure that a RegExp stack is allocated.
   9046   ExternalReference address_of_regexp_stack_memory_address =
   9047       ExternalReference::address_of_regexp_stack_memory_address();
   9048   ExternalReference address_of_regexp_stack_memory_size =
   9049       ExternalReference::address_of_regexp_stack_memory_size();
   9050   __ mov(ebx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
   9051   __ test(ebx, Operand(ebx));
   9052   __ j(zero, &runtime, not_taken);
   9053 
   9054   // Check that the first argument is a JSRegExp object.
   9055   __ mov(eax, Operand(esp, kJSRegExpOffset));
   9056   ASSERT_EQ(0, kSmiTag);
   9057   __ test(eax, Immediate(kSmiTagMask));
   9058   __ j(zero, &runtime);
   9059   __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
   9060   __ j(not_equal, &runtime);
   9061   // Check that the RegExp has been compiled (data contains a fixed array).
   9062   __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
   9063   if (FLAG_debug_code) {
   9064     __ test(ecx, Immediate(kSmiTagMask));
   9065     __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected");
   9066     __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx);
   9067     __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
   9068   }
   9069 
   9070   // ecx: RegExp data (FixedArray)
   9071   // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
   9072   __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset));
   9073   __ cmp(Operand(ebx), Immediate(Smi::FromInt(JSRegExp::IRREGEXP)));
   9074   __ j(not_equal, &runtime);
   9075 
   9076   // ecx: RegExp data (FixedArray)
   9077   // Check that the number of captures fit in the static offsets vector buffer.
   9078   __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset));
   9079   // Calculate number of capture registers (number_of_captures + 1) * 2. This
   9080   // uses the asumption that smis are 2 * their untagged value.
   9081   ASSERT_EQ(0, kSmiTag);
   9082   ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
   9083   __ add(Operand(edx), Immediate(2));  // edx was a smi.
   9084   // Check that the static offsets vector buffer is large enough.
   9085   __ cmp(edx, OffsetsVector::kStaticOffsetsVectorSize);
   9086   __ j(above, &runtime);
   9087 
   9088   // ecx: RegExp data (FixedArray)
   9089   // edx: Number of capture registers
   9090   // Check that the second argument is a string.
   9091   __ mov(eax, Operand(esp, kSubjectOffset));
   9092   __ test(eax, Immediate(kSmiTagMask));
   9093   __ j(zero, &runtime);
   9094   Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
   9095   __ j(NegateCondition(is_string), &runtime);
   9096   // Get the length of the string to ebx.
   9097   __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
   9098 
   9099   // ebx: Length of subject string
   9100   // ecx: RegExp data (FixedArray)
   9101   // edx: Number of capture registers
   9102   // Check that the third argument is a positive smi.
   9103   // Check that the third argument is a positive smi less than the subject
   9104   // string length. A negative value will be greater (usigned comparison).
   9105   __ mov(eax, Operand(esp, kPreviousIndexOffset));
   9106   __ SmiUntag(eax);
   9107   __ cmp(eax, Operand(ebx));
   9108   __ j(above, &runtime);
   9109 
   9110   // ecx: RegExp data (FixedArray)
   9111   // edx: Number of capture registers
   9112   // Check that the fourth object is a JSArray object.
   9113   __ mov(eax, Operand(esp, kLastMatchInfoOffset));
   9114   __ test(eax, Immediate(kSmiTagMask));
   9115   __ j(zero, &runtime);
   9116   __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
   9117   __ j(not_equal, &runtime);
   9118   // Check that the JSArray is in fast case.
   9119   __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
   9120   __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset));
   9121   __ cmp(eax, Factory::fixed_array_map());
   9122   __ j(not_equal, &runtime);
   9123   // Check that the last match info has space for the capture registers and the
   9124   // additional information.
   9125   __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset));
   9126   __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead));
   9127   __ cmp(edx, Operand(eax));
   9128   __ j(greater, &runtime);
   9129 
   9130   // ecx: RegExp data (FixedArray)
   9131   // Check the representation and encoding of the subject string.
   9132   Label seq_string, seq_two_byte_string, check_code;
   9133   const int kStringRepresentationEncodingMask =
   9134       kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
   9135   __ mov(eax, Operand(esp, kSubjectOffset));
   9136   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   9137   __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
   9138   __ and_(ebx, kStringRepresentationEncodingMask);
   9139   // First check for sequential string.
   9140   ASSERT_EQ(0, kStringTag);
   9141   ASSERT_EQ(0, kSeqStringTag);
   9142   __ test(Operand(ebx),
   9143           Immediate(kIsNotStringMask | kStringRepresentationMask));
   9144   __ j(zero, &seq_string);
   9145 
   9146   // Check for flat cons string.
   9147   // A flat cons string is a cons string where the second part is the empty
   9148   // string. In that case the subject string is just the first part of the cons
   9149   // string. Also in this case the first part of the cons string is known to be
   9150   // a sequential string or an external string.
   9151   __ mov(edx, ebx);
   9152   __ and_(edx, kStringRepresentationMask);
   9153   __ cmp(edx, kConsStringTag);
   9154   __ j(not_equal, &runtime);
   9155   __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
   9156   __ cmp(Operand(edx), Factory::empty_string());
   9157   __ j(not_equal, &runtime);
   9158   __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
   9159   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   9160   __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
   9161   ASSERT_EQ(0, kSeqStringTag);
   9162   __ test(ebx, Immediate(kStringRepresentationMask));
   9163   __ j(not_zero, &runtime);
   9164   __ and_(ebx, kStringRepresentationEncodingMask);
   9165 
   9166   __ bind(&seq_string);
   9167   // eax: subject string (sequential either ascii to two byte)
   9168   // ebx: suject string type & kStringRepresentationEncodingMask
   9169   // ecx: RegExp data (FixedArray)
   9170   // Check that the irregexp code has been generated for an ascii string. If
   9171   // it has, the field contains a code object otherwise it contains the hole.
   9172   __ cmp(ebx, kStringTag | kSeqStringTag | kTwoByteStringTag);
   9173   __ j(equal, &seq_two_byte_string);
   9174   if (FLAG_debug_code) {
   9175     __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
   9176     __ Check(equal, "Expected sequential ascii string");
   9177   }
   9178   __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
   9179   __ Set(edi, Immediate(1));  // Type is ascii.
   9180   __ jmp(&check_code);
   9181 
   9182   __ bind(&seq_two_byte_string);
   9183   // eax: subject string
   9184   // ecx: RegExp data (FixedArray)
   9185   __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
   9186   __ Set(edi, Immediate(0));  // Type is two byte.
   9187 
   9188   __ bind(&check_code);
   9189   // Check that the irregexp code has been generated for the actual string
   9190   // encoding. If it has, the field contains a code object otherwise it contains
   9191   // the hole.
   9192   __ CmpObjectType(edx, CODE_TYPE, ebx);
   9193   __ j(not_equal, &runtime);
   9194 
   9195   // eax: subject string
   9196   // edx: code
   9197   // edi: encoding of subject string (1 if ascii, 0 if two_byte);
   9198   // Load used arguments before starting to push arguments for call to native
   9199   // RegExp code to avoid handling changing stack height.
   9200   __ mov(ebx, Operand(esp, kPreviousIndexOffset));
   9201   __ SmiUntag(ebx);  // Previous index from smi.
   9202 
   9203   // eax: subject string
   9204   // ebx: previous index
   9205   // edx: code
   9206   // edi: encoding of subject string (1 if ascii 0 if two_byte);
   9207   // All checks done. Now push arguments for native regexp code.
   9208   __ IncrementCounter(&Counters::regexp_entry_native, 1);
   9209 
   9210   // Argument 7: Indicate that this is a direct call from JavaScript.
   9211   __ push(Immediate(1));
   9212 
   9213   // Argument 6: Start (high end) of backtracking stack memory area.
   9214   __ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address));
   9215   __ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
   9216   __ push(ecx);
   9217 
   9218   // Argument 5: static offsets vector buffer.
   9219   __ push(Immediate(ExternalReference::address_of_static_offsets_vector()));
   9220 
   9221   // Argument 4: End of string data
   9222   // Argument 3: Start of string data
   9223   Label push_two_byte, push_rest;
   9224   __ test(edi, Operand(edi));
   9225   __ mov(edi, FieldOperand(eax, String::kLengthOffset));
   9226   __ j(zero, &push_two_byte);
   9227   __ lea(ecx, FieldOperand(eax, edi, times_1, SeqAsciiString::kHeaderSize));
   9228   __ push(ecx);  // Argument 4.
   9229   __ lea(ecx, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize));
   9230   __ push(ecx);  // Argument 3.
   9231   __ jmp(&push_rest);
   9232 
   9233   __ bind(&push_two_byte);
   9234   __ lea(ecx, FieldOperand(eax, edi, times_2, SeqTwoByteString::kHeaderSize));
   9235   __ push(ecx);  // Argument 4.
   9236   __ lea(ecx, FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize));
   9237   __ push(ecx);  // Argument 3.
   9238 
   9239   __ bind(&push_rest);
   9240 
   9241   // Argument 2: Previous index.
   9242   __ push(ebx);
   9243 
   9244   // Argument 1: Subject string.
   9245   __ push(eax);
   9246 
   9247   // Locate the code entry and call it.
   9248   __ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
   9249   __ call(Operand(edx));
   9250   // Remove arguments.
   9251   __ add(Operand(esp), Immediate(7 * kPointerSize));
   9252 
   9253   // Check the result.
   9254   Label success;
   9255   __ cmp(eax, NativeRegExpMacroAssembler::SUCCESS);
   9256   __ j(equal, &success, taken);
   9257   Label failure;
   9258   __ cmp(eax, NativeRegExpMacroAssembler::FAILURE);
   9259   __ j(equal, &failure, taken);
   9260   __ cmp(eax, NativeRegExpMacroAssembler::EXCEPTION);
   9261   // If not exception it can only be retry. Handle that in the runtime system.
   9262   __ j(not_equal, &runtime);
   9263   // Result must now be exception. If there is no pending exception already a
   9264   // stack overflow (on the backtrack stack) was detected in RegExp code but
   9265   // haven't created the exception yet. Handle that in the runtime system.
   9266   // TODO(592) Rerunning the RegExp to get the stack overflow exception.
   9267   ExternalReference pending_exception(Top::k_pending_exception_address);
   9268   __ mov(eax,
   9269          Operand::StaticVariable(ExternalReference::the_hole_value_location()));
   9270   __ cmp(eax, Operand::StaticVariable(pending_exception));
   9271   __ j(equal, &runtime);
   9272   __ bind(&failure);
   9273   // For failure and exception return null.
   9274   __ mov(Operand(eax), Factory::null_value());
   9275   __ ret(4 * kPointerSize);
   9276 
   9277   // Load RegExp data.
   9278   __ bind(&success);
   9279   __ mov(eax, Operand(esp, kJSRegExpOffset));
   9280   __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
   9281   __ mov(edx, FieldOperand(ecx, JSRegExp::kIrregexpCaptureCountOffset));
   9282   // Calculate number of capture registers (number_of_captures + 1) * 2.
   9283   ASSERT_EQ(0, kSmiTag);
   9284   ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
   9285   __ add(Operand(edx), Immediate(2));  // edx was a smi.
   9286 
   9287   // edx: Number of capture registers
   9288   // Load last_match_info which is still known to be a fast case JSArray.
   9289   __ mov(eax, Operand(esp, kLastMatchInfoOffset));
   9290   __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
   9291 
   9292   // ebx: last_match_info backing store (FixedArray)
   9293   // edx: number of capture registers
   9294   // Store the capture count.
   9295   __ SmiTag(edx);  // Number of capture registers to smi.
   9296   __ mov(FieldOperand(ebx, RegExpImpl::kLastCaptureCountOffset), edx);
   9297   __ SmiUntag(edx);  // Number of capture registers back from smi.
   9298   // Store last subject and last input.
   9299   __ mov(eax, Operand(esp, kSubjectOffset));
   9300   __ mov(FieldOperand(ebx, RegExpImpl::kLastSubjectOffset), eax);
   9301   __ mov(ecx, ebx);
   9302   __ RecordWrite(ecx, RegExpImpl::kLastSubjectOffset, eax, edi);
   9303   __ mov(eax, Operand(esp, kSubjectOffset));
   9304   __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax);
   9305   __ mov(ecx, ebx);
   9306   __ RecordWrite(ecx, RegExpImpl::kLastInputOffset, eax, edi);
   9307 
   9308   // Get the static offsets vector filled by the native regexp code.
   9309   ExternalReference address_of_static_offsets_vector =
   9310       ExternalReference::address_of_static_offsets_vector();
   9311   __ mov(ecx, Immediate(address_of_static_offsets_vector));
   9312 
   9313   // ebx: last_match_info backing store (FixedArray)
   9314   // ecx: offsets vector
   9315   // edx: number of capture registers
   9316   Label next_capture, done;
   9317   __ mov(eax, Operand(esp, kPreviousIndexOffset));
   9318   // Capture register counter starts from number of capture registers and
   9319   // counts down until wraping after zero.
   9320   __ bind(&next_capture);
   9321   __ sub(Operand(edx), Immediate(1));
   9322   __ j(negative, &done);
   9323   // Read the value from the static offsets vector buffer.
   9324   __ mov(edi, Operand(ecx, edx, times_int_size, 0));
   9325   // Perform explicit shift
   9326   ASSERT_EQ(0, kSmiTag);
   9327   __ shl(edi, kSmiTagSize);
   9328   // Add previous index (from its stack slot) if value is not negative.
   9329   Label capture_negative;
   9330   // Carry flag set by shift above.
   9331   __ j(negative, &capture_negative, not_taken);
   9332   __ add(edi, Operand(eax));  // Add previous index (adding smi to smi).
   9333   __ bind(&capture_negative);
   9334   // Store the smi value in the last match info.
   9335   __ mov(FieldOperand(ebx,
   9336                       edx,
   9337                       times_pointer_size,
   9338                       RegExpImpl::kFirstCaptureOffset),
   9339                       edi);
   9340   __ jmp(&next_capture);
   9341   __ bind(&done);
   9342 
   9343   // Return last match info.
   9344   __ mov(eax, Operand(esp, kLastMatchInfoOffset));
   9345   __ ret(4 * kPointerSize);
   9346 
   9347   // Do the runtime call to execute the regexp.
   9348   __ bind(&runtime);
   9349   __ TailCallRuntime(ExternalReference(Runtime::kRegExpExec), 4, 1);
   9350 #endif  // V8_NATIVE_REGEXP
   9351 }
   9352 
   9353 
   9354 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
   9355                                                          Register object,
   9356                                                          Register result,
   9357                                                          Register scratch1,
   9358                                                          Register scratch2,
   9359                                                          bool object_is_smi,
   9360                                                          Label* not_found) {
   9361   // Currently only lookup for smis. Check for smi if object is not known to be
   9362   // a smi.
   9363   if (!object_is_smi) {
   9364     ASSERT(kSmiTag == 0);
   9365     __ test(object, Immediate(kSmiTagMask));
   9366     __ j(not_zero, not_found);
   9367   }
   9368 
   9369   // Use of registers. Register result is used as a temporary.
   9370   Register number_string_cache = result;
   9371   Register mask = scratch1;
   9372   Register scratch = scratch2;
   9373 
   9374   // Load the number string cache.
   9375   ExternalReference roots_address = ExternalReference::roots_address();
   9376   __ mov(scratch, Immediate(Heap::kNumberStringCacheRootIndex));
   9377   __ mov(number_string_cache,
   9378          Operand::StaticArray(scratch, times_pointer_size, roots_address));
   9379   // Make the hash mask from the length of the number string cache. It
   9380   // contains two elements (number and string) for each cache entry.
   9381   __ mov(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
   9382   __ shr(mask, 1);  // Divide length by two (length is not a smi).
   9383   __ sub(Operand(mask), Immediate(1));  // Make mask.
   9384   // Calculate the entry in the number string cache. The hash value in the
   9385   // number string cache for smis is just the smi value.
   9386   __ mov(scratch, object);
   9387   __ SmiUntag(scratch);
   9388   __ and_(scratch, Operand(mask));
   9389   // Check if the entry is the smi we are looking for.
   9390   __ cmp(object,
   9391          FieldOperand(number_string_cache,
   9392                       scratch,
   9393                       times_twice_pointer_size,
   9394                       FixedArray::kHeaderSize));
   9395   __ j(not_equal, not_found);
   9396 
   9397   // Get the result from the cache.
   9398   __ mov(result,
   9399          FieldOperand(number_string_cache,
   9400                       scratch,
   9401                       times_twice_pointer_size,
   9402                       FixedArray::kHeaderSize + kPointerSize));
   9403   __ IncrementCounter(&Counters::number_to_string_native, 1);
   9404 }
   9405 
   9406 
   9407 void NumberToStringStub::Generate(MacroAssembler* masm) {
   9408   Label runtime;
   9409 
   9410   __ mov(ebx, Operand(esp, kPointerSize));
   9411 
   9412   // Generate code to lookup number in the number string cache.
   9413   GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime);
   9414   __ ret(1 * kPointerSize);
   9415 
   9416   __ bind(&runtime);
   9417   // Handle number to string in the runtime system if not found in the cache.
   9418   __ TailCallRuntime(ExternalReference(Runtime::kNumberToString), 1, 1);
   9419 }
   9420 
   9421 
   9422 void CompareStub::Generate(MacroAssembler* masm) {
   9423   Label call_builtin, done;
   9424 
   9425   // NOTICE! This code is only reached after a smi-fast-case check, so
   9426   // it is certain that at least one operand isn't a smi.
   9427 
   9428   if (cc_ == equal) {  // Both strict and non-strict.
   9429     Label slow;  // Fallthrough label.
   9430     // Equality is almost reflexive (everything but NaN), so start by testing
   9431     // for "identity and not NaN".
   9432     {
   9433       Label not_identical;
   9434       __ cmp(eax, Operand(edx));
   9435       __ j(not_equal, &not_identical);
   9436       // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
   9437       // so we do the second best thing - test it ourselves.
   9438 
   9439       if (never_nan_nan_) {
   9440         __ Set(eax, Immediate(0));
   9441         __ ret(0);
   9442       } else {
   9443         Label return_equal;
   9444         Label heap_number;
   9445         // If it's not a heap number, then return equal.
   9446         __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
   9447                Immediate(Factory::heap_number_map()));
   9448         __ j(equal, &heap_number);
   9449         __ bind(&return_equal);
   9450         __ Set(eax, Immediate(0));
   9451         __ ret(0);
   9452 
   9453         __ bind(&heap_number);
   9454         // It is a heap number, so return non-equal if it's NaN and equal if
   9455         // it's not NaN.
   9456         // The representation of NaN values has all exponent bits (52..62) set,
   9457         // and not all mantissa bits (0..51) clear.
   9458         // We only accept QNaNs, which have bit 51 set.
   9459         // Read top bits of double representation (second word of value).
   9460 
   9461         // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
   9462         // all bits in the mask are set. We only need to check the word
   9463         // that contains the exponent and high bit of the mantissa.
   9464         ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
   9465         __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
   9466         __ xor_(eax, Operand(eax));
   9467         // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
   9468         // bits.
   9469         __ add(edx, Operand(edx));
   9470         __ cmp(edx, kQuietNaNHighBitsMask << 1);
   9471         __ setcc(above_equal, eax);
   9472         __ ret(0);
   9473       }
   9474 
   9475       __ bind(&not_identical);
   9476     }
   9477 
   9478     // If we're doing a strict equality comparison, we don't have to do
   9479     // type conversion, so we generate code to do fast comparison for objects
   9480     // and oddballs. Non-smi numbers and strings still go through the usual
   9481     // slow-case code.
   9482     if (strict_) {
   9483       // If either is a Smi (we know that not both are), then they can only
   9484       // be equal if the other is a HeapNumber. If so, use the slow case.
   9485       {
   9486         Label not_smis;
   9487         ASSERT_EQ(0, kSmiTag);
   9488         ASSERT_EQ(0, Smi::FromInt(0));
   9489         __ mov(ecx, Immediate(kSmiTagMask));
   9490         __ and_(ecx, Operand(eax));
   9491         __ test(ecx, Operand(edx));
   9492         __ j(not_zero, &not_smis);
   9493         // One operand is a smi.
   9494 
   9495         // Check whether the non-smi is a heap number.
   9496         ASSERT_EQ(1, kSmiTagMask);
   9497         // ecx still holds eax & kSmiTag, which is either zero or one.
   9498         __ sub(Operand(ecx), Immediate(0x01));
   9499         __ mov(ebx, edx);
   9500         __ xor_(ebx, Operand(eax));
   9501         __ and_(ebx, Operand(ecx));  // ebx holds either 0 or eax ^ edx.
   9502         __ xor_(ebx, Operand(eax));
   9503         // if eax was smi, ebx is now edx, else eax.
   9504 
   9505         // Check if the non-smi operand is a heap number.
   9506         __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
   9507                Immediate(Factory::heap_number_map()));
   9508         // If heap number, handle it in the slow case.
   9509         __ j(equal, &slow);
   9510         // Return non-equal (ebx is not zero)
   9511         __ mov(eax, ebx);
   9512         __ ret(0);
   9513 
   9514         __ bind(&not_smis);
   9515       }
   9516 
   9517       // If either operand is a JSObject or an oddball value, then they are not
   9518       // equal since their pointers are different
   9519       // There is no test for undetectability in strict equality.
   9520 
   9521       // Get the type of the first operand.
   9522       __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
   9523       __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   9524 
   9525       // If the first object is a JS object, we have done pointer comparison.
   9526       ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
   9527       Label first_non_object;
   9528       __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
   9529       __ j(less, &first_non_object);
   9530 
   9531       // Return non-zero (eax is not zero)
   9532       Label return_not_equal;
   9533       ASSERT(kHeapObjectTag != 0);
   9534       __ bind(&return_not_equal);
   9535       __ ret(0);
   9536 
   9537       __ bind(&first_non_object);
   9538       // Check for oddballs: true, false, null, undefined.
   9539       __ cmp(ecx, ODDBALL_TYPE);
   9540       __ j(equal, &return_not_equal);
   9541 
   9542       __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   9543       __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   9544 
   9545       __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
   9546       __ j(greater_equal, &return_not_equal);
   9547 
   9548       // Check for oddballs: true, false, null, undefined.
   9549       __ cmp(ecx, ODDBALL_TYPE);
   9550       __ j(equal, &return_not_equal);
   9551 
   9552       // Fall through to the general case.
   9553     }
   9554     __ bind(&slow);
   9555   }
   9556 
   9557   // Push arguments below the return address.
   9558   __ pop(ecx);
   9559   __ push(eax);
   9560   __ push(edx);
   9561   __ push(ecx);
   9562 
   9563   // Inlined floating point compare.
   9564   // Call builtin if operands are not floating point or smi.
   9565   Label check_for_symbols;
   9566   Label unordered;
   9567   if (CpuFeatures::IsSupported(SSE2)) {
   9568     CpuFeatures::Scope use_sse2(SSE2);
   9569     CpuFeatures::Scope use_cmov(CMOV);
   9570 
   9571     FloatingPointHelper::LoadSSE2Operands(masm, &check_for_symbols);
   9572     __ comisd(xmm0, xmm1);
   9573 
   9574     // Jump to builtin for NaN.
   9575     __ j(parity_even, &unordered, not_taken);
   9576     __ mov(eax, 0);  // equal
   9577     __ mov(ecx, Immediate(Smi::FromInt(1)));
   9578     __ cmov(above, eax, Operand(ecx));
   9579     __ mov(ecx, Immediate(Smi::FromInt(-1)));
   9580     __ cmov(below, eax, Operand(ecx));
   9581     __ ret(2 * kPointerSize);
   9582   } else {
   9583     FloatingPointHelper::CheckFloatOperands(masm, &check_for_symbols, ebx);
   9584     FloatingPointHelper::LoadFloatOperands(masm, ecx);
   9585     __ FCmp();
   9586 
   9587     // Jump to builtin for NaN.
   9588     __ j(parity_even, &unordered, not_taken);
   9589 
   9590     Label below_lbl, above_lbl;
   9591     // Return a result of -1, 0, or 1, to indicate result of comparison.
   9592     __ j(below, &below_lbl, not_taken);
   9593     __ j(above, &above_lbl, not_taken);
   9594 
   9595     __ xor_(eax, Operand(eax));  // equal
   9596     // Both arguments were pushed in case a runtime call was needed.
   9597     __ ret(2 * kPointerSize);
   9598 
   9599     __ bind(&below_lbl);
   9600     __ mov(eax, Immediate(Smi::FromInt(-1)));
   9601     __ ret(2 * kPointerSize);
   9602 
   9603     __ bind(&above_lbl);
   9604     __ mov(eax, Immediate(Smi::FromInt(1)));
   9605     __ ret(2 * kPointerSize);  // eax, edx were pushed
   9606   }
   9607   // If one of the numbers was NaN, then the result is always false.
   9608   // The cc is never not-equal.
   9609   __ bind(&unordered);
   9610   ASSERT(cc_ != not_equal);
   9611   if (cc_ == less || cc_ == less_equal) {
   9612     __ mov(eax, Immediate(Smi::FromInt(1)));
   9613   } else {
   9614     __ mov(eax, Immediate(Smi::FromInt(-1)));
   9615   }
   9616   __ ret(2 * kPointerSize);  // eax, edx were pushed
   9617 
   9618   // Fast negative check for symbol-to-symbol equality.
   9619   __ bind(&check_for_symbols);
   9620   Label check_for_strings;
   9621   if (cc_ == equal) {
   9622     BranchIfNonSymbol(masm, &check_for_strings, eax, ecx);
   9623     BranchIfNonSymbol(masm, &check_for_strings, edx, ecx);
   9624 
   9625     // We've already checked for object identity, so if both operands
   9626     // are symbols they aren't equal. Register eax already holds a
   9627     // non-zero value, which indicates not equal, so just return.
   9628     __ ret(2 * kPointerSize);
   9629   }
   9630 
   9631   __ bind(&check_for_strings);
   9632 
   9633   __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &call_builtin);
   9634 
   9635   // Inline comparison of ascii strings.
   9636   StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
   9637                                                      edx,
   9638                                                      eax,
   9639                                                      ecx,
   9640                                                      ebx,
   9641                                                      edi);
   9642 #ifdef DEBUG
   9643   __ Abort("Unexpected fall-through from string comparison");
   9644 #endif
   9645 
   9646   __ bind(&call_builtin);
   9647   // must swap argument order
   9648   __ pop(ecx);
   9649   __ pop(edx);
   9650   __ pop(eax);
   9651   __ push(edx);
   9652   __ push(eax);
   9653 
   9654   // Figure out which native to call and setup the arguments.
   9655   Builtins::JavaScript builtin;
   9656   if (cc_ == equal) {
   9657     builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
   9658   } else {
   9659     builtin = Builtins::COMPARE;
   9660     int ncr;  // NaN compare result
   9661     if (cc_ == less || cc_ == less_equal) {
   9662       ncr = GREATER;
   9663     } else {
   9664       ASSERT(cc_ == greater || cc_ == greater_equal);  // remaining cases
   9665       ncr = LESS;
   9666     }
   9667     __ push(Immediate(Smi::FromInt(ncr)));
   9668   }
   9669 
   9670   // Restore return address on the stack.
   9671   __ push(ecx);
   9672 
   9673   // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
   9674   // tagged as a small integer.
   9675   __ InvokeBuiltin(builtin, JUMP_FUNCTION);
   9676 }
   9677 
   9678 
   9679 void CompareStub::BranchIfNonSymbol(MacroAssembler* masm,
   9680                                     Label* label,
   9681                                     Register object,
   9682                                     Register scratch) {
   9683   __ test(object, Immediate(kSmiTagMask));
   9684   __ j(zero, label);
   9685   __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
   9686   __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
   9687   __ and_(scratch, kIsSymbolMask | kIsNotStringMask);
   9688   __ cmp(scratch, kSymbolTag | kStringTag);
   9689   __ j(not_equal, label);
   9690 }
   9691 
   9692 
   9693 void StackCheckStub::Generate(MacroAssembler* masm) {
   9694   // Because builtins always remove the receiver from the stack, we
   9695   // have to fake one to avoid underflowing the stack. The receiver
   9696   // must be inserted below the return address on the stack so we
   9697   // temporarily store that in a register.
   9698   __ pop(eax);
   9699   __ push(Immediate(Smi::FromInt(0)));
   9700   __ push(eax);
   9701 
   9702   // Do tail-call to runtime routine.
   9703   __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
   9704 }
   9705 
   9706 
   9707 void CallFunctionStub::Generate(MacroAssembler* masm) {
   9708   Label slow;
   9709 
   9710   // If the receiver might be a value (string, number or boolean) check for this
   9711   // and box it if it is.
   9712   if (ReceiverMightBeValue()) {
   9713     // Get the receiver from the stack.
   9714     // +1 ~ return address
   9715     Label receiver_is_value, receiver_is_js_object;
   9716     __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize));
   9717 
   9718     // Check if receiver is a smi (which is a number value).
   9719     __ test(eax, Immediate(kSmiTagMask));
   9720     __ j(zero, &receiver_is_value, not_taken);
   9721 
   9722     // Check if the receiver is a valid JS object.
   9723     __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edi);
   9724     __ j(above_equal, &receiver_is_js_object);
   9725 
   9726     // Call the runtime to box the value.
   9727     __ bind(&receiver_is_value);
   9728     __ EnterInternalFrame();
   9729     __ push(eax);
   9730     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   9731     __ LeaveInternalFrame();
   9732     __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax);
   9733 
   9734     __ bind(&receiver_is_js_object);
   9735   }
   9736 
   9737   // Get the function to call from the stack.
   9738   // +2 ~ receiver, return address
   9739   __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize));
   9740 
   9741   // Check that the function really is a JavaScript function.
   9742   __ test(edi, Immediate(kSmiTagMask));
   9743   __ j(zero, &slow, not_taken);
   9744   // Goto slow case if we do not have a function.
   9745   __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
   9746   __ j(not_equal, &slow, not_taken);
   9747 
   9748   // Fast-case: Just invoke the function.
   9749   ParameterCount actual(argc_);
   9750   __ InvokeFunction(edi, actual, JUMP_FUNCTION);
   9751 
   9752   // Slow-case: Non-function called.
   9753   __ bind(&slow);
   9754   // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
   9755   // of the original receiver from the call site).
   9756   __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
   9757   __ Set(eax, Immediate(argc_));
   9758   __ Set(ebx, Immediate(0));
   9759   __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
   9760   Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
   9761   __ jmp(adaptor, RelocInfo::CODE_TARGET);
   9762 }
   9763 
   9764 
   9765 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   9766   // eax holds the exception.
   9767 
   9768   // Adjust this code if not the case.
   9769   ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
   9770 
   9771   // Drop the sp to the top of the handler.
   9772   ExternalReference handler_address(Top::k_handler_address);
   9773   __ mov(esp, Operand::StaticVariable(handler_address));
   9774 
   9775   // Restore next handler and frame pointer, discard handler state.
   9776   ASSERT(StackHandlerConstants::kNextOffset == 0);
   9777   __ pop(Operand::StaticVariable(handler_address));
   9778   ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize);
   9779   __ pop(ebp);
   9780   __ pop(edx);  // Remove state.
   9781 
   9782   // Before returning we restore the context from the frame pointer if
   9783   // not NULL.  The frame pointer is NULL in the exception handler of
   9784   // a JS entry frame.
   9785   __ xor_(esi, Operand(esi));  // Tentatively set context pointer to NULL.
   9786   Label skip;
   9787   __ cmp(ebp, 0);
   9788   __ j(equal, &skip, not_taken);
   9789   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   9790   __ bind(&skip);
   9791 
   9792   ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
   9793   __ ret(0);
   9794 }
   9795 
   9796 
   9797 // If true, a Handle<T> passed by value is passed and returned by
   9798 // using the location_ field directly.  If false, it is passed and
   9799 // returned as a pointer to a handle.
   9800 #ifdef USING_MAC_ABI
   9801 static const bool kPassHandlesDirectly = true;
   9802 #else
   9803 static const bool kPassHandlesDirectly = false;
   9804 #endif
   9805 
   9806 
   9807 void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
   9808   Label get_result;
   9809   Label prologue;
   9810   Label promote_scheduled_exception;
   9811   __ EnterApiExitFrame(ExitFrame::MODE_NORMAL, kStackSpace, kArgc);
   9812   ASSERT_EQ(kArgc, 4);
   9813   if (kPassHandlesDirectly) {
   9814     // When handles as passed directly we don't have to allocate extra
   9815     // space for and pass an out parameter.
   9816     __ mov(Operand(esp, 0 * kPointerSize), ebx);  // name.
   9817     __ mov(Operand(esp, 1 * kPointerSize), eax);  // arguments pointer.
   9818   } else {
   9819     // The function expects three arguments to be passed but we allocate
   9820     // four to get space for the output cell.  The argument slots are filled
   9821     // as follows:
   9822     //
   9823     //   3: output cell
   9824     //   2: arguments pointer
   9825     //   1: name
   9826     //   0: pointer to the output cell
   9827     //
   9828     // Note that this is one more "argument" than the function expects
   9829     // so the out cell will have to be popped explicitly after returning
   9830     // from the function.
   9831     __ mov(Operand(esp, 1 * kPointerSize), ebx);  // name.
   9832     __ mov(Operand(esp, 2 * kPointerSize), eax);  // arguments pointer.
   9833     __ mov(ebx, esp);
   9834     __ add(Operand(ebx), Immediate(3 * kPointerSize));
   9835     __ mov(Operand(esp, 0 * kPointerSize), ebx);  // output
   9836     __ mov(Operand(esp, 3 * kPointerSize), Immediate(0));  // out cell.
   9837   }
   9838   // Call the api function!
   9839   __ call(fun()->address(), RelocInfo::RUNTIME_ENTRY);
   9840   // Check if the function scheduled an exception.
   9841   ExternalReference scheduled_exception_address =
   9842       ExternalReference::scheduled_exception_address();
   9843   __ cmp(Operand::StaticVariable(scheduled_exception_address),
   9844          Immediate(Factory::the_hole_value()));
   9845   __ j(not_equal, &promote_scheduled_exception, not_taken);
   9846   if (!kPassHandlesDirectly) {
   9847     // The returned value is a pointer to the handle holding the result.
   9848     // Dereference this to get to the location.
   9849     __ mov(eax, Operand(eax, 0));
   9850   }
   9851   // Check if the result handle holds 0
   9852   __ test(eax, Operand(eax));
   9853   __ j(not_zero, &get_result, taken);
   9854   // It was zero; the result is undefined.
   9855   __ mov(eax, Factory::undefined_value());
   9856   __ jmp(&prologue);
   9857   // It was non-zero.  Dereference to get the result value.
   9858   __ bind(&get_result);
   9859   __ mov(eax, Operand(eax, 0));
   9860   __ bind(&prologue);
   9861   __ LeaveExitFrame(ExitFrame::MODE_NORMAL);
   9862   __ ret(0);
   9863   __ bind(&promote_scheduled_exception);
   9864   __ TailCallRuntime(ExternalReference(Runtime::kPromoteScheduledException),
   9865                      0,
   9866                      1);
   9867 }
   9868 
   9869 
   9870 void CEntryStub::GenerateCore(MacroAssembler* masm,
   9871                               Label* throw_normal_exception,
   9872                               Label* throw_termination_exception,
   9873                               Label* throw_out_of_memory_exception,
   9874                               bool do_gc,
   9875                               bool always_allocate_scope) {
   9876   // eax: result parameter for PerformGC, if any
   9877   // ebx: pointer to C function  (C callee-saved)
   9878   // ebp: frame pointer  (restored after C call)
   9879   // esp: stack pointer  (restored after C call)
   9880   // edi: number of arguments including receiver  (C callee-saved)
   9881   // esi: pointer to the first argument (C callee-saved)
   9882 
   9883   // Result returned in eax, or eax+edx if result_size_ is 2.
   9884 
   9885   if (do_gc) {
   9886     __ mov(Operand(esp, 0 * kPointerSize), eax);  // Result.
   9887     __ call(FUNCTION_ADDR(Runtime::PerformGC), RelocInfo::RUNTIME_ENTRY);
   9888   }
   9889 
   9890   ExternalReference scope_depth =
   9891       ExternalReference::heap_always_allocate_scope_depth();
   9892   if (always_allocate_scope) {
   9893     __ inc(Operand::StaticVariable(scope_depth));
   9894   }
   9895 
   9896   // Call C function.
   9897   __ mov(Operand(esp, 0 * kPointerSize), edi);  // argc.
   9898   __ mov(Operand(esp, 1 * kPointerSize), esi);  // argv.
   9899   __ call(Operand(ebx));
   9900   // Result is in eax or edx:eax - do not destroy these registers!
   9901 
   9902   if (always_allocate_scope) {
   9903     __ dec(Operand::StaticVariable(scope_depth));
   9904   }
   9905 
   9906   // Make sure we're not trying to return 'the hole' from the runtime
   9907   // call as this may lead to crashes in the IC code later.
   9908   if (FLAG_debug_code) {
   9909     Label okay;
   9910     __ cmp(eax, Factory::the_hole_value());
   9911     __ j(not_equal, &okay);
   9912     __ int3();
   9913     __ bind(&okay);
   9914   }
   9915 
   9916   // Check for failure result.
   9917   Label failure_returned;
   9918   ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
   9919   __ lea(ecx, Operand(eax, 1));
   9920   // Lower 2 bits of ecx are 0 iff eax has failure tag.
   9921   __ test(ecx, Immediate(kFailureTagMask));
   9922   __ j(zero, &failure_returned, not_taken);
   9923 
   9924   // Exit the JavaScript to C++ exit frame.
   9925   __ LeaveExitFrame(mode_);
   9926   __ ret(0);
   9927 
   9928   // Handling of failure.
   9929   __ bind(&failure_returned);
   9930 
   9931   Label retry;
   9932   // If the returned exception is RETRY_AFTER_GC continue at retry label
   9933   ASSERT(Failure::RETRY_AFTER_GC == 0);
   9934   __ test(eax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
   9935   __ j(zero, &retry, taken);
   9936 
   9937   // Special handling of out of memory exceptions.
   9938   __ cmp(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException()));
   9939   __ j(equal, throw_out_of_memory_exception);
   9940 
   9941   // Retrieve the pending exception and clear the variable.
   9942   ExternalReference pending_exception_address(Top::k_pending_exception_address);
   9943   __ mov(eax, Operand::StaticVariable(pending_exception_address));
   9944   __ mov(edx,
   9945          Operand::StaticVariable(ExternalReference::the_hole_value_location()));
   9946   __ mov(Operand::StaticVariable(pending_exception_address), edx);
   9947 
   9948   // Special handling of termination exceptions which are uncatchable
   9949   // by javascript code.
   9950   __ cmp(eax, Factory::termination_exception());
   9951   __ j(equal, throw_termination_exception);
   9952 
   9953   // Handle normal exception.
   9954   __ jmp(throw_normal_exception);
   9955 
   9956   // Retry.
   9957   __ bind(&retry);
   9958 }
   9959 
   9960 
   9961 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
   9962                                           UncatchableExceptionType type) {
   9963   // Adjust this code if not the case.
   9964   ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
   9965 
   9966   // Drop sp to the top stack handler.
   9967   ExternalReference handler_address(Top::k_handler_address);
   9968   __ mov(esp, Operand::StaticVariable(handler_address));
   9969 
   9970   // Unwind the handlers until the ENTRY handler is found.
   9971   Label loop, done;
   9972   __ bind(&loop);
   9973   // Load the type of the current stack handler.
   9974   const int kStateOffset = StackHandlerConstants::kStateOffset;
   9975   __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY));
   9976   __ j(equal, &done);
   9977   // Fetch the next handler in the list.
   9978   const int kNextOffset = StackHandlerConstants::kNextOffset;
   9979   __ mov(esp, Operand(esp, kNextOffset));
   9980   __ jmp(&loop);
   9981   __ bind(&done);
   9982 
   9983   // Set the top handler address to next handler past the current ENTRY handler.
   9984   ASSERT(StackHandlerConstants::kNextOffset == 0);
   9985   __ pop(Operand::StaticVariable(handler_address));
   9986 
   9987   if (type == OUT_OF_MEMORY) {
   9988     // Set external caught exception to false.
   9989     ExternalReference external_caught(Top::k_external_caught_exception_address);
   9990     __ mov(eax, false);
   9991     __ mov(Operand::StaticVariable(external_caught), eax);
   9992 
   9993     // Set pending exception and eax to out of memory exception.
   9994     ExternalReference pending_exception(Top::k_pending_exception_address);
   9995     __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException()));
   9996     __ mov(Operand::StaticVariable(pending_exception), eax);
   9997   }
   9998 
   9999   // Clear the context pointer.
   10000   __ xor_(esi, Operand(esi));
   10001 
   10002   // Restore fp from handler and discard handler state.
   10003   ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize);
   10004   __ pop(ebp);
   10005   __ pop(edx);  // State.
   10006 
   10007   ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
   10008   __ ret(0);
   10009 }
   10010 
   10011 
   10012 void CEntryStub::Generate(MacroAssembler* masm) {
   10013   // eax: number of arguments including receiver
   10014   // ebx: pointer to C function  (C callee-saved)
   10015   // ebp: frame pointer  (restored after C call)
   10016   // esp: stack pointer  (restored after C call)
   10017   // esi: current context (C callee-saved)
   10018   // edi: JS function of the caller (C callee-saved)
   10019 
   10020   // NOTE: Invocations of builtins may return failure objects instead
   10021   // of a proper result. The builtin entry handles this by performing
   10022   // a garbage collection and retrying the builtin (twice).
   10023 
   10024   // Enter the exit frame that transitions from JavaScript to C++.
   10025   __ EnterExitFrame(mode_);
   10026 
   10027   // eax: result parameter for PerformGC, if any (setup below)
   10028   // ebx: pointer to builtin function  (C callee-saved)
   10029   // ebp: frame pointer  (restored after C call)
   10030   // esp: stack pointer  (restored after C call)
   10031   // edi: number of arguments including receiver (C callee-saved)
   10032   // esi: argv pointer (C callee-saved)
   10033 
   10034   Label throw_normal_exception;
   10035   Label throw_termination_exception;
   10036   Label throw_out_of_memory_exception;
   10037 
   10038   // Call into the runtime system.
   10039   GenerateCore(masm,
   10040                &throw_normal_exception,
   10041                &throw_termination_exception,
   10042                &throw_out_of_memory_exception,
   10043                false,
   10044                false);
   10045 
   10046   // Do space-specific GC and retry runtime call.
   10047   GenerateCore(masm,
   10048                &throw_normal_exception,
   10049                &throw_termination_exception,
   10050                &throw_out_of_memory_exception,
   10051                true,
   10052                false);
   10053 
   10054   // Do full GC and retry runtime call one final time.
   10055   Failure* failure = Failure::InternalError();
   10056   __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure)));
   10057   GenerateCore(masm,
   10058                &throw_normal_exception,
   10059                &throw_termination_exception,
   10060                &throw_out_of_memory_exception,
   10061                true,
   10062                true);
   10063 
   10064   __ bind(&throw_out_of_memory_exception);
   10065   GenerateThrowUncatchable(masm, OUT_OF_MEMORY);
   10066 
   10067   __ bind(&throw_termination_exception);
   10068   GenerateThrowUncatchable(masm, TERMINATION);
   10069 
   10070   __ bind(&throw_normal_exception);
   10071   GenerateThrowTOS(masm);
   10072 }
   10073 
   10074 
   10075 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   10076   Label invoke, exit;
   10077 #ifdef ENABLE_LOGGING_AND_PROFILING
   10078   Label not_outermost_js, not_outermost_js_2;
   10079 #endif
   10080 
   10081   // Setup frame.
   10082   __ push(ebp);
   10083   __ mov(ebp, Operand(esp));
   10084 
   10085   // Push marker in two places.
   10086   int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
   10087   __ push(Immediate(Smi::FromInt(marker)));  // context slot
   10088   __ push(Immediate(Smi::FromInt(marker)));  // function slot
   10089   // Save callee-saved registers (C calling conventions).
   10090   __ push(edi);
   10091   __ push(esi);
   10092   __ push(ebx);
   10093 
   10094   // Save copies of the top frame descriptor on the stack.
   10095   ExternalReference c_entry_fp(Top::k_c_entry_fp_address);
   10096   __ push(Operand::StaticVariable(c_entry_fp));
   10097 
   10098 #ifdef ENABLE_LOGGING_AND_PROFILING
   10099   // If this is the outermost JS call, set js_entry_sp value.
   10100   ExternalReference js_entry_sp(Top::k_js_entry_sp_address);
   10101   __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0));
   10102   __ j(not_equal, &not_outermost_js);
   10103   __ mov(Operand::StaticVariable(js_entry_sp), ebp);
   10104   __ bind(&not_outermost_js);
   10105 #endif
   10106 
   10107   // Call a faked try-block that does the invoke.
   10108   __ call(&invoke);
   10109 
   10110   // Caught exception: Store result (exception) in the pending
   10111   // exception field in the JSEnv and return a failure sentinel.
   10112   ExternalReference pending_exception(Top::k_pending_exception_address);
   10113   __ mov(Operand::StaticVariable(pending_exception), eax);
   10114   __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception()));
   10115   __ jmp(&exit);
   10116 
   10117   // Invoke: Link this frame into the handler chain.
   10118   __ bind(&invoke);
   10119   __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
   10120 
   10121   // Clear any pending exceptions.
   10122   __ mov(edx,
   10123          Operand::StaticVariable(ExternalReference::the_hole_value_location()));
   10124   __ mov(Operand::StaticVariable(pending_exception), edx);
   10125 
   10126   // Fake a receiver (NULL).
   10127   __ push(Immediate(0));  // receiver
   10128 
   10129   // Invoke the function by calling through JS entry trampoline
   10130   // builtin and pop the faked function when we return. Notice that we
   10131   // cannot store a reference to the trampoline code directly in this
   10132   // stub, because the builtin stubs may not have been generated yet.
   10133   if (is_construct) {
   10134     ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline);
   10135     __ mov(edx, Immediate(construct_entry));
   10136   } else {
   10137     ExternalReference entry(Builtins::JSEntryTrampoline);
   10138     __ mov(edx, Immediate(entry));
   10139   }
   10140   __ mov(edx, Operand(edx, 0));  // deref address
   10141   __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
   10142   __ call(Operand(edx));
   10143 
   10144   // Unlink this frame from the handler chain.
   10145   __ pop(Operand::StaticVariable(ExternalReference(Top::k_handler_address)));
   10146   // Pop next_sp.
   10147   __ add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize));
   10148 
   10149 #ifdef ENABLE_LOGGING_AND_PROFILING
   10150   // If current EBP value is the same as js_entry_sp value, it means that
   10151   // the current function is the outermost.
   10152   __ cmp(ebp, Operand::StaticVariable(js_entry_sp));
   10153   __ j(not_equal, &not_outermost_js_2);
   10154   __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0));
   10155   __ bind(&not_outermost_js_2);
   10156 #endif
   10157 
   10158   // Restore the top frame descriptor from the stack.
   10159   __ bind(&exit);
   10160   __ pop(Operand::StaticVariable(ExternalReference(Top::k_c_entry_fp_address)));
   10161 
   10162   // Restore callee-saved registers (C calling conventions).
   10163   __ pop(ebx);
   10164   __ pop(esi);
   10165   __ pop(edi);
   10166   __ add(Operand(esp), Immediate(2 * kPointerSize));  // remove markers
   10167 
   10168   // Restore frame pointer and return.
   10169   __ pop(ebp);
   10170   __ ret(0);
   10171 }
   10172 
   10173 
   10174 void InstanceofStub::Generate(MacroAssembler* masm) {
   10175   // Get the object - go slow case if it's a smi.
   10176   Label slow;
   10177   __ mov(eax, Operand(esp, 2 * kPointerSize));  // 2 ~ return address, function
   10178   __ test(eax, Immediate(kSmiTagMask));
   10179   __ j(zero, &slow, not_taken);
   10180 
   10181   // Check that the left hand is a JS object.
   10182   __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));  // eax - object map
   10183   __ movzx_b(ecx, FieldOperand(eax, Map::kInstanceTypeOffset));  // ecx - type
   10184   __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
   10185   __ j(less, &slow, not_taken);
   10186   __ cmp(ecx, LAST_JS_OBJECT_TYPE);
   10187   __ j(greater, &slow, not_taken);
   10188 
   10189   // Get the prototype of the function.
   10190   __ mov(edx, Operand(esp, 1 * kPointerSize));  // 1 ~ return address
   10191   __ TryGetFunctionPrototype(edx, ebx, ecx, &slow);
   10192 
   10193   // Check that the function prototype is a JS object.
   10194   __ test(ebx, Immediate(kSmiTagMask));
   10195   __ j(zero, &slow, not_taken);
   10196   __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
   10197   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   10198   __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
   10199   __ j(less, &slow, not_taken);
   10200   __ cmp(ecx, LAST_JS_OBJECT_TYPE);
   10201   __ j(greater, &slow, not_taken);
   10202 
   10203   // Register mapping: eax is object map and ebx is function prototype.
   10204   __ mov(ecx, FieldOperand(eax, Map::kPrototypeOffset));
   10205 
   10206   // Loop through the prototype chain looking for the function prototype.
   10207   Label loop, is_instance, is_not_instance;
   10208   __ bind(&loop);
   10209   __ cmp(ecx, Operand(ebx));
   10210   __ j(equal, &is_instance);
   10211   __ cmp(Operand(ecx), Immediate(Factory::null_value()));
   10212   __ j(equal, &is_not_instance);
   10213   __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
   10214   __ mov(ecx, FieldOperand(ecx, Map::kPrototypeOffset));
   10215   __ jmp(&loop);
   10216 
   10217   __ bind(&is_instance);
   10218   __ Set(eax, Immediate(0));
   10219   __ ret(2 * kPointerSize);
   10220 
   10221   __ bind(&is_not_instance);
   10222   __ Set(eax, Immediate(Smi::FromInt(1)));
   10223   __ ret(2 * kPointerSize);
   10224 
   10225   // Slow-case: Go through the JavaScript implementation.
   10226   __ bind(&slow);
   10227   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
   10228 }
   10229 
   10230 
   10231 // Unfortunately you have to run without snapshots to see most of these
   10232 // names in the profile since most compare stubs end up in the snapshot.
   10233 const char* CompareStub::GetName() {
   10234   switch (cc_) {
   10235     case less: return "CompareStub_LT";
   10236     case greater: return "CompareStub_GT";
   10237     case less_equal: return "CompareStub_LE";
   10238     case greater_equal: return "CompareStub_GE";
   10239     case not_equal: {
   10240       if (strict_) {
   10241         if (never_nan_nan_) {
   10242           return "CompareStub_NE_STRICT_NO_NAN";
   10243         } else {
   10244           return "CompareStub_NE_STRICT";
   10245         }
   10246       } else {
   10247         if (never_nan_nan_) {
   10248           return "CompareStub_NE_NO_NAN";
   10249         } else {
   10250           return "CompareStub_NE";
   10251         }
   10252       }
   10253     }
   10254     case equal: {
   10255       if (strict_) {
   10256         if (never_nan_nan_) {
   10257           return "CompareStub_EQ_STRICT_NO_NAN";
   10258         } else {
   10259           return "CompareStub_EQ_STRICT";
   10260         }
   10261       } else {
   10262         if (never_nan_nan_) {
   10263           return "CompareStub_EQ_NO_NAN";
   10264         } else {
   10265           return "CompareStub_EQ";
   10266         }
   10267       }
   10268     }
   10269     default: return "CompareStub";
   10270   }
   10271 }
   10272 
   10273 
   10274 int CompareStub::MinorKey() {
   10275   // Encode the three parameters in a unique 16 bit value.
   10276   ASSERT(static_cast<unsigned>(cc_) < (1 << 14));
   10277   int nnn_value = (never_nan_nan_ ? 2 : 0);
   10278   if (cc_ != equal) nnn_value = 0;  // Avoid duplicate stubs.
   10279   return (static_cast<unsigned>(cc_) << 2) | nnn_value | (strict_ ? 1 : 0);
   10280 }
   10281 
   10282 
   10283 void StringAddStub::Generate(MacroAssembler* masm) {
   10284   Label string_add_runtime;
   10285 
   10286   // Load the two arguments.
   10287   __ mov(eax, Operand(esp, 2 * kPointerSize));  // First argument.
   10288   __ mov(edx, Operand(esp, 1 * kPointerSize));  // Second argument.
   10289 
   10290   // Make sure that both arguments are strings if not known in advance.
   10291   if (string_check_) {
   10292     __ test(eax, Immediate(kSmiTagMask));
   10293     __ j(zero, &string_add_runtime);
   10294     __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
   10295     __ j(above_equal, &string_add_runtime);
   10296 
   10297     // First argument is a a string, test second.
   10298     __ test(edx, Immediate(kSmiTagMask));
   10299     __ j(zero, &string_add_runtime);
   10300     __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
   10301     __ j(above_equal, &string_add_runtime);
   10302   }
   10303 
   10304   // Both arguments are strings.
   10305   // eax: first string
   10306   // edx: second string
   10307   // Check if either of the strings are empty. In that case return the other.
   10308   Label second_not_zero_length, both_not_zero_length;
   10309   __ mov(ecx, FieldOperand(edx, String::kLengthOffset));
   10310   __ test(ecx, Operand(ecx));
   10311   __ j(not_zero, &second_not_zero_length);
   10312   // Second string is empty, result is first string which is already in eax.
   10313   __ IncrementCounter(&Counters::string_add_native, 1);
   10314   __ ret(2 * kPointerSize);
   10315   __ bind(&second_not_zero_length);
   10316   __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
   10317   __ test(ebx, Operand(ebx));
   10318   __ j(not_zero, &both_not_zero_length);
   10319   // First string is empty, result is second string which is in edx.
   10320   __ mov(eax, edx);
   10321   __ IncrementCounter(&Counters::string_add_native, 1);
   10322   __ ret(2 * kPointerSize);
   10323 
   10324   // Both strings are non-empty.
   10325   // eax: first string
   10326   // ebx: length of first string
   10327   // ecx: length of second string
   10328   // edx: second string
   10329   // Look at the length of the result of adding the two strings.
   10330   Label string_add_flat_result, longer_than_two;
   10331   __ bind(&both_not_zero_length);
   10332   __ add(ebx, Operand(ecx));
   10333   // Use the runtime system when adding two one character strings, as it
   10334   // contains optimizations for this specific case using the symbol table.
   10335   __ cmp(ebx, 2);
   10336   __ j(not_equal, &longer_than_two);
   10337 
   10338   // Check that both strings are non-external ascii strings.
   10339   __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
   10340                                          &string_add_runtime);
   10341 
   10342   // Get the two characters forming the sub string.
   10343   __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
   10344   __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
   10345 
   10346   // Try to lookup two character string in symbol table. If it is not found
   10347   // just allocate a new one.
   10348   Label make_two_character_string, make_flat_ascii_string;
   10349   GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi,
   10350                                        &make_two_character_string);
   10351   __ ret(2 * kPointerSize);
   10352 
   10353   __ bind(&make_two_character_string);
   10354   __ Set(ebx, Immediate(2));
   10355   __ jmp(&make_flat_ascii_string);
   10356 
   10357   __ bind(&longer_than_two);
   10358   // Check if resulting string will be flat.
   10359   __ cmp(ebx, String::kMinNonFlatLength);
   10360   __ j(below, &string_add_flat_result);
   10361   // Handle exceptionally long strings in the runtime system.
   10362   ASSERT((String::kMaxLength & 0x80000000) == 0);
   10363   __ cmp(ebx, String::kMaxLength);
   10364   __ j(above, &string_add_runtime);
   10365 
   10366   // If result is not supposed to be flat allocate a cons string object. If both
   10367   // strings are ascii the result is an ascii cons string.
   10368   Label non_ascii, allocated;
   10369   __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset));
   10370   __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset));
   10371   __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
   10372   __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset));
   10373   __ and_(ecx, Operand(edi));
   10374   ASSERT(kStringEncodingMask == kAsciiStringTag);
   10375   __ test(ecx, Immediate(kAsciiStringTag));
   10376   __ j(zero, &non_ascii);
   10377   // Allocate an acsii cons string.
   10378   __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime);
   10379   __ bind(&allocated);
   10380   // Fill the fields of the cons string.
   10381   __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx);
   10382   __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset),
   10383          Immediate(String::kEmptyHashField));
   10384   __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax);
   10385   __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx);
   10386   __ mov(eax, ecx);
   10387   __ IncrementCounter(&Counters::string_add_native, 1);
   10388   __ ret(2 * kPointerSize);
   10389   __ bind(&non_ascii);
   10390   // Allocate a two byte cons string.
   10391   __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime);
   10392   __ jmp(&allocated);
   10393 
   10394   // Handle creating a flat result. First check that both strings are not
   10395   // external strings.
   10396   // eax: first string
   10397   // ebx: length of resulting flat string
   10398   // edx: second string
   10399   __ bind(&string_add_flat_result);
   10400   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
   10401   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   10402   __ and_(ecx, kStringRepresentationMask);
   10403   __ cmp(ecx, kExternalStringTag);
   10404   __ j(equal, &string_add_runtime);
   10405   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   10406   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   10407   __ and_(ecx, kStringRepresentationMask);
   10408   __ cmp(ecx, kExternalStringTag);
   10409   __ j(equal, &string_add_runtime);
   10410   // Now check if both strings are ascii strings.
   10411   // eax: first string
   10412   // ebx: length of resulting flat string
   10413   // edx: second string
   10414   Label non_ascii_string_add_flat_result;
   10415   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
   10416   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   10417   ASSERT(kStringEncodingMask == kAsciiStringTag);
   10418   __ test(ecx, Immediate(kAsciiStringTag));
   10419   __ j(zero, &non_ascii_string_add_flat_result);
   10420   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   10421   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   10422   __ test(ecx, Immediate(kAsciiStringTag));
   10423   __ j(zero, &string_add_runtime);
   10424 
   10425   __ bind(&make_flat_ascii_string);
   10426   // Both strings are ascii strings. As they are short they are both flat.
   10427   // ebx: length of resulting flat string
   10428   __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
   10429   // eax: result string
   10430   __ mov(ecx, eax);
   10431   // Locate first character of result.
   10432   __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   10433   // Load first argument and locate first character.
   10434   __ mov(edx, Operand(esp, 2 * kPointerSize));
   10435   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
   10436   __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   10437   // eax: result string
   10438   // ecx: first character of result
   10439   // edx: first char of first argument
   10440   // edi: length of first argument
   10441   GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
   10442   // Load second argument and locate first character.
   10443   __ mov(edx, Operand(esp, 1 * kPointerSize));
   10444   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
   10445   __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   10446   // eax: result string
   10447   // ecx: next character of result
   10448   // edx: first char of second argument
   10449   // edi: length of second argument
   10450   GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
   10451   __ IncrementCounter(&Counters::string_add_native, 1);
   10452   __ ret(2 * kPointerSize);
   10453 
   10454   // Handle creating a flat two byte result.
   10455   // eax: first string - known to be two byte
   10456   // ebx: length of resulting flat string
   10457   // edx: second string
   10458   __ bind(&non_ascii_string_add_flat_result);
   10459   __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
   10460   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
   10461   __ and_(ecx, kAsciiStringTag);
   10462   __ j(not_zero, &string_add_runtime);
   10463   // Both strings are two byte strings. As they are short they are both
   10464   // flat.
   10465   __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime);
   10466   // eax: result string
   10467   __ mov(ecx, eax);
   10468   // Locate first character of result.
   10469   __ add(Operand(ecx),
   10470          Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   10471   // Load first argument and locate first character.
   10472   __ mov(edx, Operand(esp, 2 * kPointerSize));
   10473   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
   10474   __ add(Operand(edx),
   10475          Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   10476   // eax: result string
   10477   // ecx: first character of result
   10478   // edx: first char of first argument
   10479   // edi: length of first argument
   10480   GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
   10481   // Load second argument and locate first character.
   10482   __ mov(edx, Operand(esp, 1 * kPointerSize));
   10483   __ mov(edi, FieldOperand(edx, String::kLengthOffset));
   10484   __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   10485   // eax: result string
   10486   // ecx: next character of result
   10487   // edx: first char of second argument
   10488   // edi: length of second argument
   10489   GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
   10490   __ IncrementCounter(&Counters::string_add_native, 1);
   10491   __ ret(2 * kPointerSize);
   10492 
   10493   // Just jump to runtime to add the two strings.
   10494   __ bind(&string_add_runtime);
   10495   __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
   10496 }
   10497 
   10498 
   10499 void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
   10500                                             Register dest,
   10501                                             Register src,
   10502                                             Register count,
   10503                                             Register scratch,
   10504                                             bool ascii) {
   10505   Label loop;
   10506   __ bind(&loop);
   10507   // This loop just copies one character at a time, as it is only used for very
   10508   // short strings.
   10509   if (ascii) {
   10510     __ mov_b(scratch, Operand(src, 0));
   10511     __ mov_b(Operand(dest, 0), scratch);
   10512     __ add(Operand(src), Immediate(1));
   10513     __ add(Operand(dest), Immediate(1));
   10514   } else {
   10515     __ mov_w(scratch, Operand(src, 0));
   10516     __ mov_w(Operand(dest, 0), scratch);
   10517     __ add(Operand(src), Immediate(2));
   10518     __ add(Operand(dest), Immediate(2));
   10519   }
   10520   __ sub(Operand(count), Immediate(1));
   10521   __ j(not_zero, &loop);
   10522 }
   10523 
   10524 
   10525 void StringStubBase::GenerateCopyCharactersREP(MacroAssembler* masm,
   10526                                                Register dest,
   10527                                                Register src,
   10528                                                Register count,
   10529                                                Register scratch,
   10530                                                bool ascii) {
   10531   // Copy characters using rep movs of doublewords. Align destination on 4 byte
   10532   // boundary before starting rep movs. Copy remaining characters after running
   10533   // rep movs.
   10534   ASSERT(dest.is(edi));  // rep movs destination
   10535   ASSERT(src.is(esi));  // rep movs source
   10536   ASSERT(count.is(ecx));  // rep movs count
   10537   ASSERT(!scratch.is(dest));
   10538   ASSERT(!scratch.is(src));
   10539   ASSERT(!scratch.is(count));
   10540 
   10541   // Nothing to do for zero characters.
   10542   Label done;
   10543   __ test(count, Operand(count));
   10544   __ j(zero, &done);
   10545 
   10546   // Make count the number of bytes to copy.
   10547   if (!ascii) {
   10548     __ shl(count, 1);
   10549   }
   10550 
   10551   // Don't enter the rep movs if there are less than 4 bytes to copy.
   10552   Label last_bytes;
   10553   __ test(count, Immediate(~3));
   10554   __ j(zero, &last_bytes);
   10555 
   10556   // Copy from edi to esi using rep movs instruction.
   10557   __ mov(scratch, count);
   10558   __ sar(count, 2);  // Number of doublewords to copy.
   10559   __ rep_movs();
   10560 
   10561   // Find number of bytes left.
   10562   __ mov(count, scratch);
   10563   __ and_(count, 3);
   10564 
   10565   // Check if there are more bytes to copy.
   10566   __ bind(&last_bytes);
   10567   __ test(count, Operand(count));
   10568   __ j(zero, &done);
   10569 
   10570   // Copy remaining characters.
   10571   Label loop;
   10572   __ bind(&loop);
   10573   __ mov_b(scratch, Operand(src, 0));
   10574   __ mov_b(Operand(dest, 0), scratch);
   10575   __ add(Operand(src), Immediate(1));
   10576   __ add(Operand(dest), Immediate(1));
   10577   __ sub(Operand(count), Immediate(1));
   10578   __ j(not_zero, &loop);
   10579 
   10580   __ bind(&done);
   10581 }
   10582 
   10583 
   10584 void StringStubBase::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
   10585                                                           Register c1,
   10586                                                           Register c2,
   10587                                                           Register scratch1,
   10588                                                           Register scratch2,
   10589                                                           Register scratch3,
   10590                                                           Label* not_found) {
   10591   // Register scratch3 is the general scratch register in this function.
   10592   Register scratch = scratch3;
   10593 
   10594   // Make sure that both characters are not digits as such strings has a
   10595   // different hash algorithm. Don't try to look for these in the symbol table.
   10596   Label not_array_index;
   10597   __ mov(scratch, c1);
   10598   __ sub(Operand(scratch), Immediate(static_cast<int>('0')));
   10599   __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
   10600   __ j(above, &not_array_index);
   10601   __ mov(scratch, c2);
   10602   __ sub(Operand(scratch), Immediate(static_cast<int>('0')));
   10603   __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
   10604   __ j(below_equal, not_found);
   10605 
   10606   __ bind(&not_array_index);
   10607   // Calculate the two character string hash.
   10608   Register hash = scratch1;
   10609   GenerateHashInit(masm, hash, c1, scratch);
   10610   GenerateHashAddCharacter(masm, hash, c2, scratch);
   10611   GenerateHashGetHash(masm, hash, scratch);
   10612 
   10613   // Collect the two characters in a register.
   10614   Register chars = c1;
   10615   __ shl(c2, kBitsPerByte);
   10616   __ or_(chars, Operand(c2));
   10617 
   10618   // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
   10619   // hash:  hash of two character string.
   10620 
   10621   // Load the symbol table.
   10622   Register symbol_table = c2;
   10623   ExternalReference roots_address = ExternalReference::roots_address();
   10624   __ mov(scratch, Immediate(Heap::kSymbolTableRootIndex));
   10625   __ mov(symbol_table,
   10626          Operand::StaticArray(scratch, times_pointer_size, roots_address));
   10627 
   10628   // Calculate capacity mask from the symbol table capacity.
   10629   Register mask = scratch2;
   10630   static const int kCapacityOffset =
   10631       FixedArray::kHeaderSize +
   10632       SymbolTable::kCapacityIndex * kPointerSize;
   10633   __ mov(mask, FieldOperand(symbol_table, kCapacityOffset));
   10634   __ SmiUntag(mask);
   10635   __ sub(Operand(mask), Immediate(1));
   10636 
   10637   // Registers
   10638   // chars:        two character string, char 1 in byte 0 and char 2 in byte 1.
   10639   // hash:         hash of two character string
   10640   // symbol_table: symbol table
   10641   // mask:         capacity mask
   10642   // scratch:      -
   10643 
   10644   // Perform a number of probes in the symbol table.
   10645   static const int kProbes = 4;
   10646   Label found_in_symbol_table;
   10647   Label next_probe[kProbes], next_probe_pop_mask[kProbes];
   10648   for (int i = 0; i < kProbes; i++) {
   10649     // Calculate entry in symbol table.
   10650     __ mov(scratch, hash);
   10651     if (i > 0) {
   10652       __ add(Operand(scratch), Immediate(SymbolTable::GetProbeOffset(i)));
   10653     }
   10654     __ and_(scratch, Operand(mask));
   10655 
   10656     // Load the entry from the symble table.
   10657     Register candidate = scratch;  // Scratch register contains candidate.
   10658     ASSERT_EQ(1, SymbolTableShape::kEntrySize);
   10659     static const int kFirstElementOffset =
   10660         FixedArray::kHeaderSize +
   10661         SymbolTable::kPrefixStartIndex * kPointerSize +
   10662         SymbolTableShape::kPrefixSize * kPointerSize;
   10663     __ mov(candidate,
   10664            FieldOperand(symbol_table,
   10665                         scratch,
   10666                         times_pointer_size,
   10667                         kFirstElementOffset));
   10668 
   10669     // If entry is undefined no string with this hash can be found.
   10670     __ cmp(candidate, Factory::undefined_value());
   10671     __ j(equal, not_found);
   10672 
   10673     // If length is not 2 the string is not a candidate.
   10674     __ cmp(FieldOperand(candidate, String::kLengthOffset), Immediate(2));
   10675     __ j(not_equal, &next_probe[i]);
   10676 
   10677     // As we are out of registers save the mask on the stack and use that
   10678     // register as a temporary.
   10679     __ push(mask);
   10680     Register temp = mask;
   10681 
   10682     // Check that the candidate is a non-external ascii string.
   10683     __ mov(temp, FieldOperand(candidate, HeapObject::kMapOffset));
   10684     __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
   10685     __ JumpIfInstanceTypeIsNotSequentialAscii(
   10686         temp, temp, &next_probe_pop_mask[i]);
   10687 
   10688     // Check if the two characters match.
   10689     __ mov(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize));
   10690     __ and_(temp, 0x0000ffff);
   10691     __ cmp(chars, Operand(temp));
   10692     __ j(equal, &found_in_symbol_table);
   10693     __ bind(&next_probe_pop_mask[i]);
   10694     __ pop(mask);
   10695     __ bind(&next_probe[i]);
   10696   }
   10697 
   10698   // No matching 2 character string found by probing.
   10699   __ jmp(not_found);
   10700 
   10701   // Scratch register contains result when we fall through to here.
   10702   Register result = scratch;
   10703   __ bind(&found_in_symbol_table);
   10704   __ pop(mask);  // Pop temporally saved mask from the stack.
   10705   if (!result.is(eax)) {
   10706     __ mov(eax, result);
   10707   }
   10708 }
   10709 
   10710 
   10711 void StringStubBase::GenerateHashInit(MacroAssembler* masm,
   10712                                       Register hash,
   10713                                       Register character,
   10714                                       Register scratch) {
   10715   // hash = character + (character << 10);
   10716   __ mov(hash, character);
   10717   __ shl(hash, 10);
   10718   __ add(hash, Operand(character));
   10719   // hash ^= hash >> 6;
   10720   __ mov(scratch, hash);
   10721   __ sar(scratch, 6);
   10722   __ xor_(hash, Operand(scratch));
   10723 }
   10724 
   10725 
   10726 void StringStubBase::GenerateHashAddCharacter(MacroAssembler* masm,
   10727                                               Register hash,
   10728                                               Register character,
   10729                                               Register scratch) {
   10730   // hash += character;
   10731   __ add(hash, Operand(character));
   10732   // hash += hash << 10;
   10733   __ mov(scratch, hash);
   10734   __ shl(scratch, 10);
   10735   __ add(hash, Operand(scratch));
   10736   // hash ^= hash >> 6;
   10737   __ mov(scratch, hash);
   10738   __ sar(scratch, 6);
   10739   __ xor_(hash, Operand(scratch));
   10740 }
   10741 
   10742 
   10743 void StringStubBase::GenerateHashGetHash(MacroAssembler* masm,
   10744                                          Register hash,
   10745                                          Register scratch) {
   10746   // hash += hash << 3;
   10747   __ mov(scratch, hash);
   10748   __ shl(scratch, 3);
   10749   __ add(hash, Operand(scratch));
   10750   // hash ^= hash >> 11;
   10751   __ mov(scratch, hash);
   10752   __ sar(scratch, 11);
   10753   __ xor_(hash, Operand(scratch));
   10754   // hash += hash << 15;
   10755   __ mov(scratch, hash);
   10756   __ shl(scratch, 15);
   10757   __ add(hash, Operand(scratch));
   10758 
   10759   // if (hash == 0) hash = 27;
   10760   Label hash_not_zero;
   10761   __ test(hash, Operand(hash));
   10762   __ j(not_zero, &hash_not_zero);
   10763   __ mov(hash, Immediate(27));
   10764   __ bind(&hash_not_zero);
   10765 }
   10766 
   10767 
   10768 void SubStringStub::Generate(MacroAssembler* masm) {
   10769   Label runtime;
   10770 
   10771   // Stack frame on entry.
   10772   //  esp[0]: return address
   10773   //  esp[4]: to
   10774   //  esp[8]: from
   10775   //  esp[12]: string
   10776 
   10777   // Make sure first argument is a string.
   10778   __ mov(eax, Operand(esp, 3 * kPointerSize));
   10779   ASSERT_EQ(0, kSmiTag);
   10780   __ test(eax, Immediate(kSmiTagMask));
   10781   __ j(zero, &runtime);
   10782   Condition is_string = masm->IsObjectStringType(eax, ebx, ebx);
   10783   __ j(NegateCondition(is_string), &runtime);
   10784 
   10785   // eax: string
   10786   // ebx: instance type
   10787   // Calculate length of sub string using the smi values.
   10788   Label result_longer_than_two;
   10789   __ mov(ecx, Operand(esp, 1 * kPointerSize));  // To index.
   10790   __ test(ecx, Immediate(kSmiTagMask));
   10791   __ j(not_zero, &runtime);
   10792   __ mov(edx, Operand(esp, 2 * kPointerSize));  // From index.
   10793   __ test(edx, Immediate(kSmiTagMask));
   10794   __ j(not_zero, &runtime);
   10795   __ sub(ecx, Operand(edx));
   10796   // Special handling of sub-strings of length 1 and 2. One character strings
   10797   // are handled in the runtime system (looked up in the single character
   10798   // cache). Two character strings are looked for in the symbol cache.
   10799   __ SmiUntag(ecx);  // Result length is no longer smi.
   10800   __ cmp(ecx, 2);
   10801   __ j(greater, &result_longer_than_two);
   10802   __ j(less, &runtime);
   10803 
   10804   // Sub string of length 2 requested.
   10805   // eax: string
   10806   // ebx: instance type
   10807   // ecx: sub string length (value is 2)
   10808   // edx: from index (smi)
   10809   __ JumpIfInstanceTypeIsNotSequentialAscii(ebx, ebx, &runtime);
   10810 
   10811   // Get the two characters forming the sub string.
   10812   __ SmiUntag(edx);  // From index is no longer smi.
   10813   __ movzx_b(ebx, FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize));
   10814   __ movzx_b(ecx,
   10815              FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize + 1));
   10816 
   10817   // Try to lookup two character string in symbol table.
   10818   Label make_two_character_string;
   10819   GenerateTwoCharacterSymbolTableProbe(masm, ebx, ecx, eax, edx, edi,
   10820                                      &make_two_character_string);
   10821   __ ret(2 * kPointerSize);
   10822 
   10823   __ bind(&make_two_character_string);
   10824   // Setup registers for allocating the two character string.
   10825   __ mov(eax, Operand(esp, 3 * kPointerSize));
   10826   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
   10827   __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
   10828   __ Set(ecx, Immediate(2));
   10829 
   10830   __ bind(&result_longer_than_two);
   10831   // eax: string
   10832   // ebx: instance type
   10833   // ecx: result string length
   10834   // Check for flat ascii string
   10835   Label non_ascii_flat;
   10836   __ JumpIfInstanceTypeIsNotSequentialAscii(ebx, ebx, &non_ascii_flat);
   10837 
   10838   // Allocate the result.
   10839   __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime);
   10840 
   10841   // eax: result string
   10842   // ecx: result string length
   10843   __ mov(edx, esi);  // esi used by following code.
   10844   // Locate first character of result.
   10845   __ mov(edi, eax);
   10846   __ add(Operand(edi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   10847   // Load string argument and locate character of sub string start.
   10848   __ mov(esi, Operand(esp, 3 * kPointerSize));
   10849   __ add(Operand(esi), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
   10850   __ mov(ebx, Operand(esp, 2 * kPointerSize));  // from
   10851   __ SmiUntag(ebx);
   10852   __ add(esi, Operand(ebx));
   10853 
   10854   // eax: result string
   10855   // ecx: result length
   10856   // edx: original value of esi
   10857   // edi: first character of result
   10858   // esi: character of sub string start
   10859   GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
   10860   __ mov(esi, edx);  // Restore esi.
   10861   __ IncrementCounter(&Counters::sub_string_native, 1);
   10862   __ ret(3 * kPointerSize);
   10863 
   10864   __ bind(&non_ascii_flat);
   10865   // eax: string
   10866   // ebx: instance type & kStringRepresentationMask | kStringEncodingMask
   10867   // ecx: result string length
   10868   // Check for flat two byte string
   10869   __ cmp(ebx, kSeqStringTag | kTwoByteStringTag);
   10870   __ j(not_equal, &runtime);
   10871 
   10872   // Allocate the result.
   10873   __ AllocateTwoByteString(eax, ecx, ebx, edx, edi, &runtime);
   10874 
   10875   // eax: result string
   10876   // ecx: result string length
   10877   __ mov(edx, esi);  // esi used by following code.
   10878   // Locate first character of result.
   10879   __ mov(edi, eax);
   10880   __ add(Operand(edi),
   10881          Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   10882   // Load string argument and locate character of sub string start.
   10883   __ mov(esi, Operand(esp, 3 * kPointerSize));
   10884   __ add(Operand(esi),
   10885          Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
   10886   __ mov(ebx, Operand(esp, 2 * kPointerSize));  // from
   10887   // As from is a smi it is 2 times the value which matches the size of a two
   10888   // byte character.
   10889   ASSERT_EQ(0, kSmiTag);
   10890   ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
   10891   __ add(esi, Operand(ebx));
   10892 
   10893   // eax: result string
   10894   // ecx: result length
   10895   // edx: original value of esi
   10896   // edi: first character of result
   10897   // esi: character of sub string start
   10898   GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false);
   10899   __ mov(esi, edx);  // Restore esi.
   10900   __ IncrementCounter(&Counters::sub_string_native, 1);
   10901   __ ret(3 * kPointerSize);
   10902 
   10903   // Just jump to runtime to create the sub string.
   10904   __ bind(&runtime);
   10905   __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1);
   10906 }
   10907 
   10908 
   10909 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
   10910                                                         Register left,
   10911                                                         Register right,
   10912                                                         Register scratch1,
   10913                                                         Register scratch2,
   10914                                                         Register scratch3) {
   10915   Label result_not_equal;
   10916   Label result_greater;
   10917   Label compare_lengths;
   10918   // Find minimum length.
   10919   Label left_shorter;
   10920   __ mov(scratch1, FieldOperand(left, String::kLengthOffset));
   10921   __ mov(scratch3, scratch1);
   10922   __ sub(scratch3, FieldOperand(right, String::kLengthOffset));
   10923 
   10924   Register length_delta = scratch3;
   10925 
   10926   __ j(less_equal, &left_shorter);
   10927   // Right string is shorter. Change scratch1 to be length of right string.
   10928   __ sub(scratch1, Operand(length_delta));
   10929   __ bind(&left_shorter);
   10930 
   10931   Register min_length = scratch1;
   10932 
   10933   // If either length is zero, just compare lengths.
   10934   __ test(min_length, Operand(min_length));
   10935   __ j(zero, &compare_lengths);
   10936 
   10937   // Change index to run from -min_length to -1 by adding min_length
   10938   // to string start. This means that loop ends when index reaches zero,
   10939   // which doesn't need an additional compare.
   10940   __ lea(left,
   10941          FieldOperand(left,
   10942                       min_length, times_1,
   10943                       SeqAsciiString::kHeaderSize));
   10944   __ lea(right,
   10945          FieldOperand(right,
   10946                       min_length, times_1,
   10947                       SeqAsciiString::kHeaderSize));
   10948   __ neg(min_length);
   10949 
   10950   Register index = min_length;  // index = -min_length;
   10951 
   10952   {
   10953     // Compare loop.
   10954     Label loop;
   10955     __ bind(&loop);
   10956     // Compare characters.
   10957     __ mov_b(scratch2, Operand(left, index, times_1, 0));
   10958     __ cmpb(scratch2, Operand(right, index, times_1, 0));
   10959     __ j(not_equal, &result_not_equal);
   10960     __ add(Operand(index), Immediate(1));
   10961     __ j(not_zero, &loop);
   10962   }
   10963 
   10964   // Compare lengths -  strings up to min-length are equal.
   10965   __ bind(&compare_lengths);
   10966   __ test(length_delta, Operand(length_delta));
   10967   __ j(not_zero, &result_not_equal);
   10968 
   10969   // Result is EQUAL.
   10970   ASSERT_EQ(0, EQUAL);
   10971   ASSERT_EQ(0, kSmiTag);
   10972   __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
   10973   __ ret(2 * kPointerSize);
   10974 
   10975   __ bind(&result_not_equal);
   10976   __ j(greater, &result_greater);
   10977 
   10978   // Result is LESS.
   10979   __ Set(eax, Immediate(Smi::FromInt(LESS)));
   10980   __ ret(2 * kPointerSize);
   10981 
   10982   // Result is GREATER.
   10983   __ bind(&result_greater);
   10984   __ Set(eax, Immediate(Smi::FromInt(GREATER)));
   10985   __ ret(2 * kPointerSize);
   10986 }
   10987 
   10988 
   10989 void StringCompareStub::Generate(MacroAssembler* masm) {
   10990   Label runtime;
   10991 
   10992   // Stack frame on entry.
   10993   //  esp[0]: return address
   10994   //  esp[4]: right string
   10995   //  esp[8]: left string
   10996 
   10997   __ mov(edx, Operand(esp, 2 * kPointerSize));  // left
   10998   __ mov(eax, Operand(esp, 1 * kPointerSize));  // right
   10999 
   11000   Label not_same;
   11001   __ cmp(edx, Operand(eax));
   11002   __ j(not_equal, &not_same);
   11003   ASSERT_EQ(0, EQUAL);
   11004   ASSERT_EQ(0, kSmiTag);
   11005   __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
   11006   __ IncrementCounter(&Counters::string_compare_native, 1);
   11007   __ ret(2 * kPointerSize);
   11008 
   11009   __ bind(&not_same);
   11010 
   11011   // Check that both objects are sequential ascii strings.
   11012   __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime);
   11013 
   11014   // Compare flat ascii strings.
   11015   __ IncrementCounter(&Counters::string_compare_native, 1);
   11016   GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi);
   11017 
   11018   // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
   11019   // tagged as a small integer.
   11020   __ bind(&runtime);
   11021   __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
   11022 }
   11023 
   11024 #undef __
   11025 
   11026 } }  // namespace v8::internal
   11027