Land http://codereview.chromium.org/1311003/diff/8001/9001 to allows us to push to...
[platform/upstream/v8.git] / src / x64 / codegen-x64.cc
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 "parser.h"
36 #include "regexp-macro-assembler.h"
37 #include "register-allocator-inl.h"
38 #include "scopes.h"
39 #include "virtual-frame-inl.h"
40
41 namespace v8 {
42 namespace internal {
43
44 #define __ ACCESS_MASM(masm_)
45
46 // -------------------------------------------------------------------------
47 // Platform-specific DeferredCode functions.
48
49 void DeferredCode::SaveRegisters() {
50   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
51     int action = registers_[i];
52     if (action == kPush) {
53       __ push(RegisterAllocator::ToRegister(i));
54     } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
55       __ movq(Operand(rbp, action), RegisterAllocator::ToRegister(i));
56     }
57   }
58 }
59
60
61 void DeferredCode::RestoreRegisters() {
62   // Restore registers in reverse order due to the stack.
63   for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
64     int action = registers_[i];
65     if (action == kPush) {
66       __ pop(RegisterAllocator::ToRegister(i));
67     } else if (action != kIgnore) {
68       action &= ~kSyncedFlag;
69       __ movq(RegisterAllocator::ToRegister(i), Operand(rbp, action));
70     }
71   }
72 }
73
74
75 // -------------------------------------------------------------------------
76 // CodeGenState implementation.
77
78 CodeGenState::CodeGenState(CodeGenerator* owner)
79     : owner_(owner),
80       destination_(NULL),
81       previous_(NULL) {
82   owner_->set_state(this);
83 }
84
85
86 CodeGenState::CodeGenState(CodeGenerator* owner,
87                            ControlDestination* destination)
88     : owner_(owner),
89       destination_(destination),
90       previous_(owner->state()) {
91   owner_->set_state(this);
92 }
93
94
95 CodeGenState::~CodeGenState() {
96   ASSERT(owner_->state() == this);
97   owner_->set_state(previous_);
98 }
99
100
101 // -------------------------------------------------------------------------
102 // Deferred code objects
103 //
104 // These subclasses of DeferredCode add pieces of code to the end of generated
105 // code.  They are branched to from the generated code, and
106 // keep some slower code out of the main body of the generated code.
107 // Many of them call a code stub or a runtime function.
108
109 class DeferredInlineSmiAdd: public DeferredCode {
110  public:
111   DeferredInlineSmiAdd(Register dst,
112                        Smi* value,
113                        OverwriteMode overwrite_mode)
114       : dst_(dst), value_(value), overwrite_mode_(overwrite_mode) {
115     set_comment("[ DeferredInlineSmiAdd");
116   }
117
118   virtual void Generate();
119
120  private:
121   Register dst_;
122   Smi* value_;
123   OverwriteMode overwrite_mode_;
124 };
125
126
127 // The result of value + src is in dst.  It either overflowed or was not
128 // smi tagged.  Undo the speculative addition and call the appropriate
129 // specialized stub for add.  The result is left in dst.
130 class DeferredInlineSmiAddReversed: public DeferredCode {
131  public:
132   DeferredInlineSmiAddReversed(Register dst,
133                                Smi* value,
134                                OverwriteMode overwrite_mode)
135       : dst_(dst), value_(value), overwrite_mode_(overwrite_mode) {
136     set_comment("[ DeferredInlineSmiAddReversed");
137   }
138
139   virtual void Generate();
140
141  private:
142   Register dst_;
143   Smi* value_;
144   OverwriteMode overwrite_mode_;
145 };
146
147
148 class DeferredInlineSmiSub: public DeferredCode {
149  public:
150   DeferredInlineSmiSub(Register dst,
151                        Smi* value,
152                        OverwriteMode overwrite_mode)
153       : dst_(dst), value_(value), overwrite_mode_(overwrite_mode) {
154     set_comment("[ DeferredInlineSmiSub");
155   }
156
157   virtual void Generate();
158
159  private:
160   Register dst_;
161   Smi* value_;
162   OverwriteMode overwrite_mode_;
163 };
164
165
166 // Call the appropriate binary operation stub to compute src op value
167 // and leave the result in dst.
168 class DeferredInlineSmiOperation: public DeferredCode {
169  public:
170   DeferredInlineSmiOperation(Token::Value op,
171                              Register dst,
172                              Register src,
173                              Smi* value,
174                              OverwriteMode overwrite_mode)
175       : op_(op),
176         dst_(dst),
177         src_(src),
178         value_(value),
179         overwrite_mode_(overwrite_mode) {
180     set_comment("[ DeferredInlineSmiOperation");
181   }
182
183   virtual void Generate();
184
185  private:
186   Token::Value op_;
187   Register dst_;
188   Register src_;
189   Smi* value_;
190   OverwriteMode overwrite_mode_;
191 };
192
193
194 class FloatingPointHelper : public AllStatic {
195  public:
196   // Code pattern for loading a floating point value. Input value must
197   // be either a smi or a heap number object (fp value). Requirements:
198   // operand on TOS+1. Returns operand as floating point number on FPU
199   // stack.
200   static void LoadFloatOperand(MacroAssembler* masm, Register scratch);
201
202   // Code pattern for loading a floating point value. Input value must
203   // be either a smi or a heap number object (fp value). Requirements:
204   // operand in src register. Returns operand as floating point number
205   // in XMM register
206   static void LoadFloatOperand(MacroAssembler* masm,
207                                Register src,
208                                XMMRegister dst);
209
210   // Code pattern for loading floating point values. Input values must
211   // be either smi or heap number objects (fp values). Requirements:
212   // operand_1 in rdx, operand_2 in rax; Returns operands as
213   // floating point numbers in XMM registers.
214   static void LoadFloatOperands(MacroAssembler* masm,
215                                 XMMRegister dst1,
216                                 XMMRegister dst2);
217
218   // Similar to LoadFloatOperands, assumes that the operands are smis.
219   static void LoadFloatOperandsFromSmis(MacroAssembler* masm,
220                                         XMMRegister dst1,
221                                         XMMRegister dst2);
222
223   // Code pattern for loading floating point values onto the fp stack.
224   // Input values must be either smi or heap number objects (fp values).
225   // Requirements:
226   // Register version: operands in registers lhs and rhs.
227   // Stack version: operands on TOS+1 and TOS+2.
228   // Returns operands as floating point numbers on fp stack.
229   static void LoadFloatOperands(MacroAssembler* masm,
230                                 Register lhs,
231                                 Register rhs);
232
233   // Test if operands are smi or number objects (fp). Requirements:
234   // operand_1 in rax, operand_2 in rdx; falls through on float or smi
235   // operands, jumps to the non_float label otherwise.
236   static void CheckNumberOperands(MacroAssembler* masm,
237                                   Label* non_float);
238
239   // Takes the operands in rdx and rax and loads them as integers in rax
240   // and rcx.
241   static void LoadAsIntegers(MacroAssembler* masm,
242                              bool use_sse3,
243                              Label* operand_conversion_failure);
244 };
245
246
247 // -----------------------------------------------------------------------------
248 // CodeGenerator implementation.
249
250 CodeGenerator::CodeGenerator(MacroAssembler* masm)
251     : deferred_(8),
252       masm_(masm),
253       info_(NULL),
254       frame_(NULL),
255       allocator_(NULL),
256       state_(NULL),
257       loop_nesting_(0),
258       function_return_is_shadowed_(false),
259       in_spilled_code_(false) {
260 }
261
262
263 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
264   // Call the runtime to declare the globals.  The inevitable call
265   // will sync frame elements to memory anyway, so we do it eagerly to
266   // allow us to push the arguments directly into place.
267   frame_->SyncRange(0, frame_->element_count() - 1);
268
269   __ movq(kScratchRegister, pairs, RelocInfo::EMBEDDED_OBJECT);
270   frame_->EmitPush(rsi);  // The context is the first argument.
271   frame_->EmitPush(kScratchRegister);
272   frame_->EmitPush(Smi::FromInt(is_eval() ? 1 : 0));
273   Result ignored = frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
274   // Return value is ignored.
275 }
276
277
278 void CodeGenerator::Generate(CompilationInfo* info) {
279   // Record the position for debugging purposes.
280   CodeForFunctionPosition(info->function());
281   Comment cmnt(masm_, "[ function compiled by virtual frame code generator");
282
283   // Initialize state.
284   info_ = info;
285   ASSERT(allocator_ == NULL);
286   RegisterAllocator register_allocator(this);
287   allocator_ = &register_allocator;
288   ASSERT(frame_ == NULL);
289   frame_ = new VirtualFrame();
290   set_in_spilled_code(false);
291
292   // Adjust for function-level loop nesting.
293   loop_nesting_ += info->loop_nesting();
294
295   JumpTarget::set_compiling_deferred_code(false);
296
297 #ifdef DEBUG
298   if (strlen(FLAG_stop_at) > 0 &&
299       info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
300     frame_->SpillAll();
301     __ int3();
302   }
303 #endif
304
305   // New scope to get automatic timing calculation.
306   {  // NOLINT
307     HistogramTimerScope codegen_timer(&Counters::code_generation);
308     CodeGenState state(this);
309
310     // Entry:
311     // Stack: receiver, arguments, return address.
312     // rbp: caller's frame pointer
313     // rsp: stack pointer
314     // rdi: called JS function
315     // rsi: callee's context
316     allocator_->Initialize();
317
318     if (info->mode() == CompilationInfo::PRIMARY) {
319       frame_->Enter();
320
321       // Allocate space for locals and initialize them.
322       frame_->AllocateStackSlots();
323
324       // Allocate the local context if needed.
325       int heap_slots = scope()->num_heap_slots();
326       if (heap_slots > 0) {
327         Comment cmnt(masm_, "[ allocate local context");
328         // Allocate local context.
329         // Get outer context and create a new context based on it.
330         frame_->PushFunction();
331         Result context;
332         if (heap_slots <= FastNewContextStub::kMaximumSlots) {
333           FastNewContextStub stub(heap_slots);
334           context = frame_->CallStub(&stub, 1);
335         } else {
336           context = frame_->CallRuntime(Runtime::kNewContext, 1);
337         }
338
339         // Update context local.
340         frame_->SaveContextRegister();
341
342         // Verify that the runtime call result and rsi agree.
343         if (FLAG_debug_code) {
344           __ cmpq(context.reg(), rsi);
345           __ Assert(equal, "Runtime::NewContext should end up in rsi");
346         }
347       }
348
349       // TODO(1241774): Improve this code:
350       // 1) only needed if we have a context
351       // 2) no need to recompute context ptr every single time
352       // 3) don't copy parameter operand code from SlotOperand!
353       {
354         Comment cmnt2(masm_, "[ copy context parameters into .context");
355         // Note that iteration order is relevant here! If we have the same
356         // parameter twice (e.g., function (x, y, x)), and that parameter
357         // needs to be copied into the context, it must be the last argument
358         // passed to the parameter that needs to be copied. This is a rare
359         // case so we don't check for it, instead we rely on the copying
360         // order: such a parameter is copied repeatedly into the same
361         // context location and thus the last value is what is seen inside
362         // the function.
363         for (int i = 0; i < scope()->num_parameters(); i++) {
364           Variable* par = scope()->parameter(i);
365           Slot* slot = par->slot();
366           if (slot != NULL && slot->type() == Slot::CONTEXT) {
367             // The use of SlotOperand below is safe in unspilled code
368             // because the slot is guaranteed to be a context slot.
369             //
370             // There are no parameters in the global scope.
371             ASSERT(!scope()->is_global_scope());
372             frame_->PushParameterAt(i);
373             Result value = frame_->Pop();
374             value.ToRegister();
375
376             // SlotOperand loads context.reg() with the context object
377             // stored to, used below in RecordWrite.
378             Result context = allocator_->Allocate();
379             ASSERT(context.is_valid());
380             __ movq(SlotOperand(slot, context.reg()), value.reg());
381             int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
382             Result scratch = allocator_->Allocate();
383             ASSERT(scratch.is_valid());
384             frame_->Spill(context.reg());
385             frame_->Spill(value.reg());
386             __ RecordWrite(context.reg(), offset, value.reg(), scratch.reg());
387           }
388         }
389       }
390
391       // Store the arguments object.  This must happen after context
392       // initialization because the arguments object may be stored in
393       // the context.
394       if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) {
395         StoreArgumentsObject(true);
396       }
397
398       // Initialize ThisFunction reference if present.
399       if (scope()->is_function_scope() && scope()->function() != NULL) {
400         frame_->Push(Factory::the_hole_value());
401         StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT);
402       }
403     } else {
404       // When used as the secondary compiler for splitting, rbp, rsi,
405       // and rdi have been pushed on the stack.  Adjust the virtual
406       // frame to match this state.
407       frame_->Adjust(3);
408       allocator_->Unuse(rdi);
409
410       // Bind all the bailout labels to the beginning of the function.
411       List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
412       for (int i = 0; i < bailouts->length(); i++) {
413         __ bind(bailouts->at(i)->label());
414       }
415     }
416
417     // Initialize the function return target after the locals are set
418     // up, because it needs the expected frame height from the frame.
419     function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
420     function_return_is_shadowed_ = false;
421
422     // Generate code to 'execute' declarations and initialize functions
423     // (source elements). In case of an illegal redeclaration we need to
424     // handle that instead of processing the declarations.
425     if (scope()->HasIllegalRedeclaration()) {
426       Comment cmnt(masm_, "[ illegal redeclarations");
427       scope()->VisitIllegalRedeclaration(this);
428     } else {
429       Comment cmnt(masm_, "[ declarations");
430       ProcessDeclarations(scope()->declarations());
431       // Bail out if a stack-overflow exception occurred when processing
432       // declarations.
433       if (HasStackOverflow()) return;
434     }
435
436     if (FLAG_trace) {
437       frame_->CallRuntime(Runtime::kTraceEnter, 0);
438       // Ignore the return value.
439     }
440     CheckStack();
441
442     // Compile the body of the function in a vanilla state. Don't
443     // bother compiling all the code if the scope has an illegal
444     // redeclaration.
445     if (!scope()->HasIllegalRedeclaration()) {
446       Comment cmnt(masm_, "[ function body");
447 #ifdef DEBUG
448       bool is_builtin = Bootstrapper::IsActive();
449       bool should_trace =
450           is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
451       if (should_trace) {
452         frame_->CallRuntime(Runtime::kDebugTrace, 0);
453         // Ignore the return value.
454       }
455 #endif
456       VisitStatements(info->function()->body());
457
458       // Handle the return from the function.
459       if (has_valid_frame()) {
460         // If there is a valid frame, control flow can fall off the end of
461         // the body.  In that case there is an implicit return statement.
462         ASSERT(!function_return_is_shadowed_);
463         CodeForReturnPosition(info->function());
464         frame_->PrepareForReturn();
465         Result undefined(Factory::undefined_value());
466         if (function_return_.is_bound()) {
467           function_return_.Jump(&undefined);
468         } else {
469           function_return_.Bind(&undefined);
470           GenerateReturnSequence(&undefined);
471         }
472       } else if (function_return_.is_linked()) {
473         // If the return target has dangling jumps to it, then we have not
474         // yet generated the return sequence.  This can happen when (a)
475         // control does not flow off the end of the body so we did not
476         // compile an artificial return statement just above, and (b) there
477         // are return statements in the body but (c) they are all shadowed.
478         Result return_value;
479         function_return_.Bind(&return_value);
480         GenerateReturnSequence(&return_value);
481       }
482     }
483   }
484
485   // Adjust for function-level loop nesting.
486   loop_nesting_ -= info->loop_nesting();
487
488   // Code generation state must be reset.
489   ASSERT(state_ == NULL);
490   ASSERT(loop_nesting() == 0);
491   ASSERT(!function_return_is_shadowed_);
492   function_return_.Unuse();
493   DeleteFrame();
494
495   // Process any deferred code using the register allocator.
496   if (!HasStackOverflow()) {
497     HistogramTimerScope deferred_timer(&Counters::deferred_code_generation);
498     JumpTarget::set_compiling_deferred_code(true);
499     ProcessDeferred();
500     JumpTarget::set_compiling_deferred_code(false);
501   }
502
503   // There is no need to delete the register allocator, it is a
504   // stack-allocated local.
505   allocator_ = NULL;
506 }
507
508 void CodeGenerator::GenerateReturnSequence(Result* return_value) {
509   // The return value is a live (but not currently reference counted)
510   // reference to rax.  This is safe because the current frame does not
511   // contain a reference to rax (it is prepared for the return by spilling
512   // all registers).
513   if (FLAG_trace) {
514     frame_->Push(return_value);
515     *return_value = frame_->CallRuntime(Runtime::kTraceExit, 1);
516   }
517   return_value->ToRegister(rax);
518
519   // Add a label for checking the size of the code used for returning.
520 #ifdef DEBUG
521   Label check_exit_codesize;
522   masm_->bind(&check_exit_codesize);
523 #endif
524
525   // Leave the frame and return popping the arguments and the
526   // receiver.
527   frame_->Exit();
528   masm_->ret((scope()->num_parameters() + 1) * kPointerSize);
529 #ifdef ENABLE_DEBUGGER_SUPPORT
530   // Add padding that will be overwritten by a debugger breakpoint.
531   // frame_->Exit() generates "movq rsp, rbp; pop rbp; ret k"
532   // with length 7 (3 + 1 + 3).
533   const int kPadding = Assembler::kJSReturnSequenceLength - 7;
534   for (int i = 0; i < kPadding; ++i) {
535     masm_->int3();
536   }
537   // Check that the size of the code used for returning matches what is
538   // expected by the debugger.
539   ASSERT_EQ(Assembler::kJSReturnSequenceLength,
540             masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
541 #endif
542   DeleteFrame();
543 }
544
545
546 #ifdef DEBUG
547 bool CodeGenerator::HasValidEntryRegisters() {
548   return (allocator()->count(rax) == (frame()->is_used(rax) ? 1 : 0))
549       && (allocator()->count(rbx) == (frame()->is_used(rbx) ? 1 : 0))
550       && (allocator()->count(rcx) == (frame()->is_used(rcx) ? 1 : 0))
551       && (allocator()->count(rdx) == (frame()->is_used(rdx) ? 1 : 0))
552       && (allocator()->count(rdi) == (frame()->is_used(rdi) ? 1 : 0))
553       && (allocator()->count(r8) == (frame()->is_used(r8) ? 1 : 0))
554       && (allocator()->count(r9) == (frame()->is_used(r9) ? 1 : 0))
555       && (allocator()->count(r11) == (frame()->is_used(r11) ? 1 : 0))
556       && (allocator()->count(r14) == (frame()->is_used(r14) ? 1 : 0))
557       && (allocator()->count(r15) == (frame()->is_used(r15) ? 1 : 0))
558       && (allocator()->count(r12) == (frame()->is_used(r12) ? 1 : 0));
559 }
560 #endif
561
562
563 class DeferredReferenceGetKeyedValue: public DeferredCode {
564  public:
565   explicit DeferredReferenceGetKeyedValue(Register dst,
566                                           Register receiver,
567                                           Register key,
568                                           bool is_global)
569       : dst_(dst), receiver_(receiver), key_(key), is_global_(is_global) {
570     set_comment("[ DeferredReferenceGetKeyedValue");
571   }
572
573   virtual void Generate();
574
575   Label* patch_site() { return &patch_site_; }
576
577  private:
578   Label patch_site_;
579   Register dst_;
580   Register receiver_;
581   Register key_;
582   bool is_global_;
583 };
584
585
586 void DeferredReferenceGetKeyedValue::Generate() {
587   __ push(receiver_);  // First IC argument.
588   __ push(key_);       // Second IC argument.
589
590   // Calculate the delta from the IC call instruction to the map check
591   // movq instruction in the inlined version.  This delta is stored in
592   // a test(rax, delta) instruction after the call so that we can find
593   // it in the IC initialization code and patch the movq instruction.
594   // This means that we cannot allow test instructions after calls to
595   // KeyedLoadIC stubs in other places.
596   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
597   RelocInfo::Mode mode = is_global_
598                          ? RelocInfo::CODE_TARGET_CONTEXT
599                          : RelocInfo::CODE_TARGET;
600   __ Call(ic, mode);
601   // The delta from the start of the map-compare instruction to the
602   // test instruction.  We use masm_-> directly here instead of the __
603   // macro because the macro sometimes uses macro expansion to turn
604   // into something that can't return a value.  This is encountered
605   // when doing generated code coverage tests.
606   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
607   // Here we use masm_-> instead of the __ macro because this is the
608   // instruction that gets patched and coverage code gets in the way.
609   // TODO(X64): Consider whether it's worth switching the test to a
610   // 7-byte NOP with non-zero immediate (0f 1f 80 xxxxxxxx) which won't
611   // be generated normally.
612   masm_->testl(rax, Immediate(-delta_to_patch_site));
613   __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
614
615   if (!dst_.is(rax)) __ movq(dst_, rax);
616   __ pop(key_);
617   __ pop(receiver_);
618 }
619
620
621 class DeferredReferenceSetKeyedValue: public DeferredCode {
622  public:
623   DeferredReferenceSetKeyedValue(Register value,
624                                  Register key,
625                                  Register receiver)
626       : value_(value), key_(key), receiver_(receiver) {
627     set_comment("[ DeferredReferenceSetKeyedValue");
628   }
629
630   virtual void Generate();
631
632   Label* patch_site() { return &patch_site_; }
633
634  private:
635   Register value_;
636   Register key_;
637   Register receiver_;
638   Label patch_site_;
639 };
640
641
642 void DeferredReferenceSetKeyedValue::Generate() {
643   __ IncrementCounter(&Counters::keyed_store_inline_miss, 1);
644   // Push receiver and key arguments on the stack.
645   __ push(receiver_);
646   __ push(key_);
647   // Move value argument to eax as expected by the IC stub.
648   if (!value_.is(rax)) __ movq(rax, value_);
649   // Call the IC stub.
650   Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
651   __ Call(ic, RelocInfo::CODE_TARGET);
652   // The delta from the start of the map-compare instructions (initial movq)
653   // to the test instruction.  We use masm_-> directly here instead of the
654   // __ macro because the macro sometimes uses macro expansion to turn
655   // into something that can't return a value.  This is encountered
656   // when doing generated code coverage tests.
657   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
658   // Here we use masm_-> instead of the __ macro because this is the
659   // instruction that gets patched and coverage code gets in the way.
660   masm_->testl(rax, Immediate(-delta_to_patch_site));
661   // Restore value (returned from store IC), key and receiver
662   // registers.
663   if (!value_.is(rax)) __ movq(value_, rax);
664   __ pop(key_);
665   __ pop(receiver_);
666 }
667
668
669 void CodeGenerator::CallApplyLazy(Expression* applicand,
670                                   Expression* receiver,
671                                   VariableProxy* arguments,
672                                   int position) {
673   // An optimized implementation of expressions of the form
674   // x.apply(y, arguments).
675   // If the arguments object of the scope has not been allocated,
676   // and x.apply is Function.prototype.apply, this optimization
677   // just copies y and the arguments of the current function on the
678   // stack, as receiver and arguments, and calls x.
679   // In the implementation comments, we call x the applicand
680   // and y the receiver.
681   ASSERT(ArgumentsMode() == LAZY_ARGUMENTS_ALLOCATION);
682   ASSERT(arguments->IsArguments());
683
684   // Load applicand.apply onto the stack. This will usually
685   // give us a megamorphic load site. Not super, but it works.
686   Load(applicand);
687   Handle<String> name = Factory::LookupAsciiSymbol("apply");
688   frame()->Push(name);
689   Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET);
690   __ nop();
691   frame()->Push(&answer);
692
693   // Load the receiver and the existing arguments object onto the
694   // expression stack. Avoid allocating the arguments object here.
695   Load(receiver);
696   LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
697
698   // Emit the source position information after having loaded the
699   // receiver and the arguments.
700   CodeForSourcePosition(position);
701   // Contents of frame at this point:
702   // Frame[0]: arguments object of the current function or the hole.
703   // Frame[1]: receiver
704   // Frame[2]: applicand.apply
705   // Frame[3]: applicand.
706
707   // Check if the arguments object has been lazily allocated
708   // already. If so, just use that instead of copying the arguments
709   // from the stack. This also deals with cases where a local variable
710   // named 'arguments' has been introduced.
711   frame_->Dup();
712   Result probe = frame_->Pop();
713   { VirtualFrame::SpilledScope spilled_scope;
714     Label slow, done;
715     bool try_lazy = true;
716     if (probe.is_constant()) {
717       try_lazy = probe.handle()->IsTheHole();
718     } else {
719       __ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex);
720       probe.Unuse();
721       __ j(not_equal, &slow);
722     }
723
724     if (try_lazy) {
725       Label build_args;
726       // Get rid of the arguments object probe.
727       frame_->Drop();  // Can be called on a spilled frame.
728       // Stack now has 3 elements on it.
729       // Contents of stack at this point:
730       // rsp[0]: receiver
731       // rsp[1]: applicand.apply
732       // rsp[2]: applicand.
733
734       // Check that the receiver really is a JavaScript object.
735       __ movq(rax, Operand(rsp, 0));
736       Condition is_smi = masm_->CheckSmi(rax);
737       __ j(is_smi, &build_args);
738       // We allow all JSObjects including JSFunctions.  As long as
739       // JS_FUNCTION_TYPE is the last instance type and it is right
740       // after LAST_JS_OBJECT_TYPE, we do not have to check the upper
741       // bound.
742       ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
743       ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
744       __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
745       __ j(below, &build_args);
746
747       // Check that applicand.apply is Function.prototype.apply.
748       __ movq(rax, Operand(rsp, kPointerSize));
749       is_smi = masm_->CheckSmi(rax);
750       __ j(is_smi, &build_args);
751       __ CmpObjectType(rax, JS_FUNCTION_TYPE, rcx);
752       __ j(not_equal, &build_args);
753       __ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
754       Handle<Code> apply_code(Builtins::builtin(Builtins::FunctionApply));
755       __ Cmp(FieldOperand(rax, SharedFunctionInfo::kCodeOffset), apply_code);
756       __ j(not_equal, &build_args);
757
758       // Check that applicand is a function.
759       __ movq(rdi, Operand(rsp, 2 * kPointerSize));
760       is_smi = masm_->CheckSmi(rdi);
761       __ j(is_smi, &build_args);
762       __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
763       __ j(not_equal, &build_args);
764
765       // Copy the arguments to this function possibly from the
766       // adaptor frame below it.
767       Label invoke, adapted;
768       __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
769       __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
770                     Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
771       __ j(equal, &adapted);
772
773       // No arguments adaptor frame. Copy fixed number of arguments.
774       __ movq(rax, Immediate(scope()->num_parameters()));
775       for (int i = 0; i < scope()->num_parameters(); i++) {
776         __ push(frame_->ParameterAt(i));
777       }
778       __ jmp(&invoke);
779
780       // Arguments adaptor frame present. Copy arguments from there, but
781       // avoid copying too many arguments to avoid stack overflows.
782       __ bind(&adapted);
783       static const uint32_t kArgumentsLimit = 1 * KB;
784       __ movq(rax, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
785       __ SmiToInteger32(rax, rax);
786       __ movq(rcx, rax);
787       __ cmpq(rax, Immediate(kArgumentsLimit));
788       __ j(above, &build_args);
789
790       // Loop through the arguments pushing them onto the execution
791       // stack. We don't inform the virtual frame of the push, so we don't
792       // have to worry about getting rid of the elements from the virtual
793       // frame.
794       Label loop;
795       // rcx is a small non-negative integer, due to the test above.
796       __ testl(rcx, rcx);
797       __ j(zero, &invoke);
798       __ bind(&loop);
799       __ push(Operand(rdx, rcx, times_pointer_size, 1 * kPointerSize));
800       __ decl(rcx);
801       __ j(not_zero, &loop);
802
803       // Invoke the function.
804       __ bind(&invoke);
805       ParameterCount actual(rax);
806       __ InvokeFunction(rdi, actual, CALL_FUNCTION);
807       // Drop applicand.apply and applicand from the stack, and push
808       // the result of the function call, but leave the spilled frame
809       // unchanged, with 3 elements, so it is correct when we compile the
810       // slow-case code.
811       __ addq(rsp, Immediate(2 * kPointerSize));
812       __ push(rax);
813       // Stack now has 1 element:
814       //   rsp[0]: result
815       __ jmp(&done);
816
817       // Slow-case: Allocate the arguments object since we know it isn't
818       // there, and fall-through to the slow-case where we call
819       // applicand.apply.
820       __ bind(&build_args);
821       // Stack now has 3 elements, because we have jumped from where:
822       // rsp[0]: receiver
823       // rsp[1]: applicand.apply
824       // rsp[2]: applicand.
825
826       // StoreArgumentsObject requires a correct frame, and may modify it.
827       Result arguments_object = StoreArgumentsObject(false);
828       frame_->SpillAll();
829       arguments_object.ToRegister();
830       frame_->EmitPush(arguments_object.reg());
831       arguments_object.Unuse();
832       // Stack and frame now have 4 elements.
833       __ bind(&slow);
834     }
835
836     // Generic computation of x.apply(y, args) with no special optimization.
837     // Flip applicand.apply and applicand on the stack, so
838     // applicand looks like the receiver of the applicand.apply call.
839     // Then process it as a normal function call.
840     __ movq(rax, Operand(rsp, 3 * kPointerSize));
841     __ movq(rbx, Operand(rsp, 2 * kPointerSize));
842     __ movq(Operand(rsp, 2 * kPointerSize), rax);
843     __ movq(Operand(rsp, 3 * kPointerSize), rbx);
844
845     CallFunctionStub call_function(2, NOT_IN_LOOP, NO_CALL_FUNCTION_FLAGS);
846     Result res = frame_->CallStub(&call_function, 3);
847     // The function and its two arguments have been dropped.
848     frame_->Drop(1);  // Drop the receiver as well.
849     res.ToRegister();
850     frame_->EmitPush(res.reg());
851     // Stack now has 1 element:
852     //   rsp[0]: result
853     if (try_lazy) __ bind(&done);
854   }  // End of spilled scope.
855   // Restore the context register after a call.
856   frame_->RestoreContextRegister();
857 }
858
859
860 class DeferredStackCheck: public DeferredCode {
861  public:
862   DeferredStackCheck() {
863     set_comment("[ DeferredStackCheck");
864   }
865
866   virtual void Generate();
867 };
868
869
870 void DeferredStackCheck::Generate() {
871   StackCheckStub stub;
872   __ CallStub(&stub);
873 }
874
875
876 void CodeGenerator::CheckStack() {
877   DeferredStackCheck* deferred = new DeferredStackCheck;
878   __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
879   deferred->Branch(below);
880   deferred->BindExit();
881 }
882
883
884 void CodeGenerator::VisitAndSpill(Statement* statement) {
885   // TODO(X64): No architecture specific code. Move to shared location.
886   ASSERT(in_spilled_code());
887   set_in_spilled_code(false);
888   Visit(statement);
889   if (frame_ != NULL) {
890     frame_->SpillAll();
891   }
892   set_in_spilled_code(true);
893 }
894
895
896 void CodeGenerator::VisitStatementsAndSpill(ZoneList<Statement*>* statements) {
897   ASSERT(in_spilled_code());
898   set_in_spilled_code(false);
899   VisitStatements(statements);
900   if (frame_ != NULL) {
901     frame_->SpillAll();
902   }
903   set_in_spilled_code(true);
904 }
905
906
907 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
908   ASSERT(!in_spilled_code());
909   for (int i = 0; has_valid_frame() && i < statements->length(); i++) {
910     Visit(statements->at(i));
911   }
912 }
913
914
915 void CodeGenerator::VisitBlock(Block* node) {
916   ASSERT(!in_spilled_code());
917   Comment cmnt(masm_, "[ Block");
918   CodeForStatementPosition(node);
919   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
920   VisitStatements(node->statements());
921   if (node->break_target()->is_linked()) {
922     node->break_target()->Bind();
923   }
924   node->break_target()->Unuse();
925 }
926
927
928 void CodeGenerator::VisitDeclaration(Declaration* node) {
929   Comment cmnt(masm_, "[ Declaration");
930   Variable* var = node->proxy()->var();
931   ASSERT(var != NULL);  // must have been resolved
932   Slot* slot = var->slot();
933
934   // If it was not possible to allocate the variable at compile time,
935   // we need to "declare" it at runtime to make sure it actually
936   // exists in the local context.
937   if (slot != NULL && slot->type() == Slot::LOOKUP) {
938     // Variables with a "LOOKUP" slot were introduced as non-locals
939     // during variable resolution and must have mode DYNAMIC.
940     ASSERT(var->is_dynamic());
941     // For now, just do a runtime call.  Sync the virtual frame eagerly
942     // so we can simply push the arguments into place.
943     frame_->SyncRange(0, frame_->element_count() - 1);
944     frame_->EmitPush(rsi);
945     __ movq(kScratchRegister, var->name(), RelocInfo::EMBEDDED_OBJECT);
946     frame_->EmitPush(kScratchRegister);
947     // Declaration nodes are always introduced in one of two modes.
948     ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST);
949     PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY;
950     frame_->EmitPush(Smi::FromInt(attr));
951     // Push initial value, if any.
952     // Note: For variables we must not push an initial value (such as
953     // 'undefined') because we may have a (legal) redeclaration and we
954     // must not destroy the current value.
955     if (node->mode() == Variable::CONST) {
956       frame_->EmitPush(Heap::kTheHoleValueRootIndex);
957     } else if (node->fun() != NULL) {
958       Load(node->fun());
959     } else {
960       frame_->EmitPush(Smi::FromInt(0));  // no initial value!
961     }
962     Result ignored = frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
963     // Ignore the return value (declarations are statements).
964     return;
965   }
966
967   ASSERT(!var->is_global());
968
969   // If we have a function or a constant, we need to initialize the variable.
970   Expression* val = NULL;
971   if (node->mode() == Variable::CONST) {
972     val = new Literal(Factory::the_hole_value());
973   } else {
974     val = node->fun();  // NULL if we don't have a function
975   }
976
977   if (val != NULL) {
978     {
979       // Set the initial value.
980       Reference target(this, node->proxy());
981       Load(val);
982       target.SetValue(NOT_CONST_INIT);
983       // The reference is removed from the stack (preserving TOS) when
984       // it goes out of scope.
985     }
986     // Get rid of the assigned value (declarations are statements).
987     frame_->Drop();
988   }
989 }
990
991
992 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
993   ASSERT(!in_spilled_code());
994   Comment cmnt(masm_, "[ ExpressionStatement");
995   CodeForStatementPosition(node);
996   Expression* expression = node->expression();
997   expression->MarkAsStatement();
998   Load(expression);
999   // Remove the lingering expression result from the top of stack.
1000   frame_->Drop();
1001 }
1002
1003
1004 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1005   ASSERT(!in_spilled_code());
1006   Comment cmnt(masm_, "// EmptyStatement");
1007   CodeForStatementPosition(node);
1008   // nothing to do
1009 }
1010
1011
1012 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1013   ASSERT(!in_spilled_code());
1014   Comment cmnt(masm_, "[ IfStatement");
1015   // Generate different code depending on which parts of the if statement
1016   // are present or not.
1017   bool has_then_stm = node->HasThenStatement();
1018   bool has_else_stm = node->HasElseStatement();
1019
1020   CodeForStatementPosition(node);
1021   JumpTarget exit;
1022   if (has_then_stm && has_else_stm) {
1023     JumpTarget then;
1024     JumpTarget else_;
1025     ControlDestination dest(&then, &else_, true);
1026     LoadCondition(node->condition(), &dest, true);
1027
1028     if (dest.false_was_fall_through()) {
1029       // The else target was bound, so we compile the else part first.
1030       Visit(node->else_statement());
1031
1032       // We may have dangling jumps to the then part.
1033       if (then.is_linked()) {
1034         if (has_valid_frame()) exit.Jump();
1035         then.Bind();
1036         Visit(node->then_statement());
1037       }
1038     } else {
1039       // The then target was bound, so we compile the then part first.
1040       Visit(node->then_statement());
1041
1042       if (else_.is_linked()) {
1043         if (has_valid_frame()) exit.Jump();
1044         else_.Bind();
1045         Visit(node->else_statement());
1046       }
1047     }
1048
1049   } else if (has_then_stm) {
1050     ASSERT(!has_else_stm);
1051     JumpTarget then;
1052     ControlDestination dest(&then, &exit, true);
1053     LoadCondition(node->condition(), &dest, true);
1054
1055     if (dest.false_was_fall_through()) {
1056       // The exit label was bound.  We may have dangling jumps to the
1057       // then part.
1058       if (then.is_linked()) {
1059         exit.Unuse();
1060         exit.Jump();
1061         then.Bind();
1062         Visit(node->then_statement());
1063       }
1064     } else {
1065       // The then label was bound.
1066       Visit(node->then_statement());
1067     }
1068
1069   } else if (has_else_stm) {
1070     ASSERT(!has_then_stm);
1071     JumpTarget else_;
1072     ControlDestination dest(&exit, &else_, false);
1073     LoadCondition(node->condition(), &dest, true);
1074
1075     if (dest.true_was_fall_through()) {
1076       // The exit label was bound.  We may have dangling jumps to the
1077       // else part.
1078       if (else_.is_linked()) {
1079         exit.Unuse();
1080         exit.Jump();
1081         else_.Bind();
1082         Visit(node->else_statement());
1083       }
1084     } else {
1085       // The else label was bound.
1086       Visit(node->else_statement());
1087     }
1088
1089   } else {
1090     ASSERT(!has_then_stm && !has_else_stm);
1091     // We only care about the condition's side effects (not its value
1092     // or control flow effect).  LoadCondition is called without
1093     // forcing control flow.
1094     ControlDestination dest(&exit, &exit, true);
1095     LoadCondition(node->condition(), &dest, false);
1096     if (!dest.is_used()) {
1097       // We got a value on the frame rather than (or in addition to)
1098       // control flow.
1099       frame_->Drop();
1100     }
1101   }
1102
1103   if (exit.is_linked()) {
1104     exit.Bind();
1105   }
1106 }
1107
1108
1109 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
1110   ASSERT(!in_spilled_code());
1111   Comment cmnt(masm_, "[ ContinueStatement");
1112   CodeForStatementPosition(node);
1113   node->target()->continue_target()->Jump();
1114 }
1115
1116
1117 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1118   ASSERT(!in_spilled_code());
1119   Comment cmnt(masm_, "[ BreakStatement");
1120   CodeForStatementPosition(node);
1121   node->target()->break_target()->Jump();
1122 }
1123
1124
1125 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1126   ASSERT(!in_spilled_code());
1127   Comment cmnt(masm_, "[ ReturnStatement");
1128
1129   CodeForStatementPosition(node);
1130   Load(node->expression());
1131   Result return_value = frame_->Pop();
1132   if (function_return_is_shadowed_) {
1133     function_return_.Jump(&return_value);
1134   } else {
1135     frame_->PrepareForReturn();
1136     if (function_return_.is_bound()) {
1137       // If the function return label is already bound we reuse the
1138       // code by jumping to the return site.
1139       function_return_.Jump(&return_value);
1140     } else {
1141       function_return_.Bind(&return_value);
1142       GenerateReturnSequence(&return_value);
1143     }
1144   }
1145 }
1146
1147
1148 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1149   ASSERT(!in_spilled_code());
1150   Comment cmnt(masm_, "[ WithEnterStatement");
1151   CodeForStatementPosition(node);
1152   Load(node->expression());
1153   Result context;
1154   if (node->is_catch_block()) {
1155     context = frame_->CallRuntime(Runtime::kPushCatchContext, 1);
1156   } else {
1157     context = frame_->CallRuntime(Runtime::kPushContext, 1);
1158   }
1159
1160   // Update context local.
1161   frame_->SaveContextRegister();
1162
1163   // Verify that the runtime call result and rsi agree.
1164   if (FLAG_debug_code) {
1165     __ cmpq(context.reg(), rsi);
1166     __ Assert(equal, "Runtime::NewContext should end up in rsi");
1167   }
1168 }
1169
1170
1171 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1172   ASSERT(!in_spilled_code());
1173   Comment cmnt(masm_, "[ WithExitStatement");
1174   CodeForStatementPosition(node);
1175   // Pop context.
1176   __ movq(rsi, ContextOperand(rsi, Context::PREVIOUS_INDEX));
1177   // Update context local.
1178   frame_->SaveContextRegister();
1179 }
1180
1181
1182 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1183   // TODO(X64): This code is completely generic and should be moved somewhere
1184   // where it can be shared between architectures.
1185   ASSERT(!in_spilled_code());
1186   Comment cmnt(masm_, "[ SwitchStatement");
1187   CodeForStatementPosition(node);
1188   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1189
1190   // Compile the switch value.
1191   Load(node->tag());
1192
1193   ZoneList<CaseClause*>* cases = node->cases();
1194   int length = cases->length();
1195   CaseClause* default_clause = NULL;
1196
1197   JumpTarget next_test;
1198   // Compile the case label expressions and comparisons.  Exit early
1199   // if a comparison is unconditionally true.  The target next_test is
1200   // bound before the loop in order to indicate control flow to the
1201   // first comparison.
1202   next_test.Bind();
1203   for (int i = 0; i < length && !next_test.is_unused(); i++) {
1204     CaseClause* clause = cases->at(i);
1205     // The default is not a test, but remember it for later.
1206     if (clause->is_default()) {
1207       default_clause = clause;
1208       continue;
1209     }
1210
1211     Comment cmnt(masm_, "[ Case comparison");
1212     // We recycle the same target next_test for each test.  Bind it if
1213     // the previous test has not done so and then unuse it for the
1214     // loop.
1215     if (next_test.is_linked()) {
1216       next_test.Bind();
1217     }
1218     next_test.Unuse();
1219
1220     // Duplicate the switch value.
1221     frame_->Dup();
1222
1223     // Compile the label expression.
1224     Load(clause->label());
1225
1226     // Compare and branch to the body if true or the next test if
1227     // false.  Prefer the next test as a fall through.
1228     ControlDestination dest(clause->body_target(), &next_test, false);
1229     Comparison(node, equal, true, &dest);
1230
1231     // If the comparison fell through to the true target, jump to the
1232     // actual body.
1233     if (dest.true_was_fall_through()) {
1234       clause->body_target()->Unuse();
1235       clause->body_target()->Jump();
1236     }
1237   }
1238
1239   // If there was control flow to a next test from the last one
1240   // compiled, compile a jump to the default or break target.
1241   if (!next_test.is_unused()) {
1242     if (next_test.is_linked()) {
1243       next_test.Bind();
1244     }
1245     // Drop the switch value.
1246     frame_->Drop();
1247     if (default_clause != NULL) {
1248       default_clause->body_target()->Jump();
1249     } else {
1250       node->break_target()->Jump();
1251     }
1252   }
1253
1254   // The last instruction emitted was a jump, either to the default
1255   // clause or the break target, or else to a case body from the loop
1256   // that compiles the tests.
1257   ASSERT(!has_valid_frame());
1258   // Compile case bodies as needed.
1259   for (int i = 0; i < length; i++) {
1260     CaseClause* clause = cases->at(i);
1261
1262     // There are two ways to reach the body: from the corresponding
1263     // test or as the fall through of the previous body.
1264     if (clause->body_target()->is_linked() || has_valid_frame()) {
1265       if (clause->body_target()->is_linked()) {
1266         if (has_valid_frame()) {
1267           // If we have both a jump to the test and a fall through, put
1268           // a jump on the fall through path to avoid the dropping of
1269           // the switch value on the test path.  The exception is the
1270           // default which has already had the switch value dropped.
1271           if (clause->is_default()) {
1272             clause->body_target()->Bind();
1273           } else {
1274             JumpTarget body;
1275             body.Jump();
1276             clause->body_target()->Bind();
1277             frame_->Drop();
1278             body.Bind();
1279           }
1280         } else {
1281           // No fall through to worry about.
1282           clause->body_target()->Bind();
1283           if (!clause->is_default()) {
1284             frame_->Drop();
1285           }
1286         }
1287       } else {
1288         // Otherwise, we have only fall through.
1289         ASSERT(has_valid_frame());
1290       }
1291
1292       // We are now prepared to compile the body.
1293       Comment cmnt(masm_, "[ Case body");
1294       VisitStatements(clause->statements());
1295     }
1296     clause->body_target()->Unuse();
1297   }
1298
1299   // We may not have a valid frame here so bind the break target only
1300   // if needed.
1301   if (node->break_target()->is_linked()) {
1302     node->break_target()->Bind();
1303   }
1304   node->break_target()->Unuse();
1305 }
1306
1307
1308 void CodeGenerator::VisitDoWhileStatement(DoWhileStatement* node) {
1309   ASSERT(!in_spilled_code());
1310   Comment cmnt(masm_, "[ DoWhileStatement");
1311   CodeForStatementPosition(node);
1312   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1313   JumpTarget body(JumpTarget::BIDIRECTIONAL);
1314   IncrementLoopNesting();
1315
1316   ConditionAnalysis info = AnalyzeCondition(node->cond());
1317   // Label the top of the loop for the backward jump if necessary.
1318   switch (info) {
1319     case ALWAYS_TRUE:
1320       // Use the continue target.
1321       node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1322       node->continue_target()->Bind();
1323       break;
1324     case ALWAYS_FALSE:
1325       // No need to label it.
1326       node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1327       break;
1328     case DONT_KNOW:
1329       // Continue is the test, so use the backward body target.
1330       node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1331       body.Bind();
1332       break;
1333   }
1334
1335   CheckStack();  // TODO(1222600): ignore if body contains calls.
1336   Visit(node->body());
1337
1338   // Compile the test.
1339   switch (info) {
1340     case ALWAYS_TRUE:
1341       // If control flow can fall off the end of the body, jump back
1342       // to the top and bind the break target at the exit.
1343       if (has_valid_frame()) {
1344         node->continue_target()->Jump();
1345       }
1346       if (node->break_target()->is_linked()) {
1347         node->break_target()->Bind();
1348       }
1349       break;
1350     case ALWAYS_FALSE:
1351       // We may have had continues or breaks in the body.
1352       if (node->continue_target()->is_linked()) {
1353         node->continue_target()->Bind();
1354       }
1355       if (node->break_target()->is_linked()) {
1356         node->break_target()->Bind();
1357       }
1358       break;
1359     case DONT_KNOW:
1360       // We have to compile the test expression if it can be reached by
1361       // control flow falling out of the body or via continue.
1362       if (node->continue_target()->is_linked()) {
1363         node->continue_target()->Bind();
1364       }
1365       if (has_valid_frame()) {
1366         Comment cmnt(masm_, "[ DoWhileCondition");
1367         CodeForDoWhileConditionPosition(node);
1368         ControlDestination dest(&body, node->break_target(), false);
1369         LoadCondition(node->cond(), &dest, true);
1370       }
1371       if (node->break_target()->is_linked()) {
1372         node->break_target()->Bind();
1373       }
1374       break;
1375   }
1376
1377   DecrementLoopNesting();
1378   node->continue_target()->Unuse();
1379   node->break_target()->Unuse();
1380 }
1381
1382
1383 void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
1384   ASSERT(!in_spilled_code());
1385   Comment cmnt(masm_, "[ WhileStatement");
1386   CodeForStatementPosition(node);
1387
1388   // If the condition is always false and has no side effects, we do not
1389   // need to compile anything.
1390   ConditionAnalysis info = AnalyzeCondition(node->cond());
1391   if (info == ALWAYS_FALSE) return;
1392
1393   // Do not duplicate conditions that may have function literal
1394   // subexpressions.  This can cause us to compile the function literal
1395   // twice.
1396   bool test_at_bottom = !node->may_have_function_literal();
1397   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1398   IncrementLoopNesting();
1399   JumpTarget body;
1400   if (test_at_bottom) {
1401     body.set_direction(JumpTarget::BIDIRECTIONAL);
1402   }
1403
1404   // Based on the condition analysis, compile the test as necessary.
1405   switch (info) {
1406     case ALWAYS_TRUE:
1407       // We will not compile the test expression.  Label the top of the
1408       // loop with the continue target.
1409       node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1410       node->continue_target()->Bind();
1411       break;
1412     case DONT_KNOW: {
1413       if (test_at_bottom) {
1414         // Continue is the test at the bottom, no need to label the test
1415         // at the top.  The body is a backward target.
1416         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1417       } else {
1418         // Label the test at the top as the continue target.  The body
1419         // is a forward-only target.
1420         node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1421         node->continue_target()->Bind();
1422       }
1423       // Compile the test with the body as the true target and preferred
1424       // fall-through and with the break target as the false target.
1425       ControlDestination dest(&body, node->break_target(), true);
1426       LoadCondition(node->cond(), &dest, true);
1427
1428       if (dest.false_was_fall_through()) {
1429         // If we got the break target as fall-through, the test may have
1430         // been unconditionally false (if there are no jumps to the
1431         // body).
1432         if (!body.is_linked()) {
1433           DecrementLoopNesting();
1434           return;
1435         }
1436
1437         // Otherwise, jump around the body on the fall through and then
1438         // bind the body target.
1439         node->break_target()->Unuse();
1440         node->break_target()->Jump();
1441         body.Bind();
1442       }
1443       break;
1444     }
1445     case ALWAYS_FALSE:
1446       UNREACHABLE();
1447       break;
1448   }
1449
1450   CheckStack();  // TODO(1222600): ignore if body contains calls.
1451   Visit(node->body());
1452
1453   // Based on the condition analysis, compile the backward jump as
1454   // necessary.
1455   switch (info) {
1456     case ALWAYS_TRUE:
1457       // The loop body has been labeled with the continue target.
1458       if (has_valid_frame()) {
1459         node->continue_target()->Jump();
1460       }
1461       break;
1462     case DONT_KNOW:
1463       if (test_at_bottom) {
1464         // If we have chosen to recompile the test at the bottom,
1465         // then it is the continue target.
1466         if (node->continue_target()->is_linked()) {
1467           node->continue_target()->Bind();
1468         }
1469         if (has_valid_frame()) {
1470           // The break target is the fall-through (body is a backward
1471           // jump from here and thus an invalid fall-through).
1472           ControlDestination dest(&body, node->break_target(), false);
1473           LoadCondition(node->cond(), &dest, true);
1474         }
1475       } else {
1476         // If we have chosen not to recompile the test at the
1477         // bottom, jump back to the one at the top.
1478         if (has_valid_frame()) {
1479           node->continue_target()->Jump();
1480         }
1481       }
1482       break;
1483     case ALWAYS_FALSE:
1484       UNREACHABLE();
1485       break;
1486   }
1487
1488   // The break target may be already bound (by the condition), or there
1489   // may not be a valid frame.  Bind it only if needed.
1490   if (node->break_target()->is_linked()) {
1491     node->break_target()->Bind();
1492   }
1493   DecrementLoopNesting();
1494 }
1495
1496
1497 void CodeGenerator::VisitForStatement(ForStatement* node) {
1498   ASSERT(!in_spilled_code());
1499   Comment cmnt(masm_, "[ ForStatement");
1500   CodeForStatementPosition(node);
1501
1502   // Compile the init expression if present.
1503   if (node->init() != NULL) {
1504     Visit(node->init());
1505   }
1506
1507   // If the condition is always false and has no side effects, we do not
1508   // need to compile anything else.
1509   ConditionAnalysis info = AnalyzeCondition(node->cond());
1510   if (info == ALWAYS_FALSE) return;
1511
1512   // Do not duplicate conditions that may have function literal
1513   // subexpressions.  This can cause us to compile the function literal
1514   // twice.
1515   bool test_at_bottom = !node->may_have_function_literal();
1516   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1517   IncrementLoopNesting();
1518
1519   // Target for backward edge if no test at the bottom, otherwise
1520   // unused.
1521   JumpTarget loop(JumpTarget::BIDIRECTIONAL);
1522
1523   // Target for backward edge if there is a test at the bottom,
1524   // otherwise used as target for test at the top.
1525   JumpTarget body;
1526   if (test_at_bottom) {
1527     body.set_direction(JumpTarget::BIDIRECTIONAL);
1528   }
1529
1530   // Based on the condition analysis, compile the test as necessary.
1531   switch (info) {
1532     case ALWAYS_TRUE:
1533       // We will not compile the test expression.  Label the top of the
1534       // loop.
1535       if (node->next() == NULL) {
1536         // Use the continue target if there is no update expression.
1537         node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1538         node->continue_target()->Bind();
1539       } else {
1540         // Otherwise use the backward loop target.
1541         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1542         loop.Bind();
1543       }
1544       break;
1545     case DONT_KNOW: {
1546       if (test_at_bottom) {
1547         // Continue is either the update expression or the test at the
1548         // bottom, no need to label the test at the top.
1549         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1550       } else if (node->next() == NULL) {
1551         // We are not recompiling the test at the bottom and there is no
1552         // update expression.
1553         node->continue_target()->set_direction(JumpTarget::BIDIRECTIONAL);
1554         node->continue_target()->Bind();
1555       } else {
1556         // We are not recompiling the test at the bottom and there is an
1557         // update expression.
1558         node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1559         loop.Bind();
1560       }
1561
1562       // Compile the test with the body as the true target and preferred
1563       // fall-through and with the break target as the false target.
1564       ControlDestination dest(&body, node->break_target(), true);
1565       LoadCondition(node->cond(), &dest, true);
1566
1567       if (dest.false_was_fall_through()) {
1568         // If we got the break target as fall-through, the test may have
1569         // been unconditionally false (if there are no jumps to the
1570         // body).
1571         if (!body.is_linked()) {
1572           DecrementLoopNesting();
1573           return;
1574         }
1575
1576         // Otherwise, jump around the body on the fall through and then
1577         // bind the body target.
1578         node->break_target()->Unuse();
1579         node->break_target()->Jump();
1580         body.Bind();
1581       }
1582       break;
1583     }
1584     case ALWAYS_FALSE:
1585       UNREACHABLE();
1586       break;
1587   }
1588
1589   CheckStack();  // TODO(1222600): ignore if body contains calls.
1590   Visit(node->body());
1591
1592   // If there is an update expression, compile it if necessary.
1593   if (node->next() != NULL) {
1594     if (node->continue_target()->is_linked()) {
1595       node->continue_target()->Bind();
1596     }
1597
1598     // Control can reach the update by falling out of the body or by a
1599     // continue.
1600     if (has_valid_frame()) {
1601       // Record the source position of the statement as this code which
1602       // is after the code for the body actually belongs to the loop
1603       // statement and not the body.
1604       CodeForStatementPosition(node);
1605       Visit(node->next());
1606     }
1607   }
1608
1609   // Based on the condition analysis, compile the backward jump as
1610   // necessary.
1611   switch (info) {
1612     case ALWAYS_TRUE:
1613       if (has_valid_frame()) {
1614         if (node->next() == NULL) {
1615           node->continue_target()->Jump();
1616         } else {
1617           loop.Jump();
1618         }
1619       }
1620       break;
1621     case DONT_KNOW:
1622       if (test_at_bottom) {
1623         if (node->continue_target()->is_linked()) {
1624           // We can have dangling jumps to the continue target if there
1625           // was no update expression.
1626           node->continue_target()->Bind();
1627         }
1628         // Control can reach the test at the bottom by falling out of
1629         // the body, by a continue in the body, or from the update
1630         // expression.
1631         if (has_valid_frame()) {
1632           // The break target is the fall-through (body is a backward
1633           // jump from here).
1634           ControlDestination dest(&body, node->break_target(), false);
1635           LoadCondition(node->cond(), &dest, true);
1636         }
1637       } else {
1638         // Otherwise, jump back to the test at the top.
1639         if (has_valid_frame()) {
1640           if (node->next() == NULL) {
1641             node->continue_target()->Jump();
1642           } else {
1643             loop.Jump();
1644           }
1645         }
1646       }
1647       break;
1648     case ALWAYS_FALSE:
1649       UNREACHABLE();
1650       break;
1651   }
1652
1653   // The break target may be already bound (by the condition), or there
1654   // may not be a valid frame.  Bind it only if needed.
1655   if (node->break_target()->is_linked()) {
1656     node->break_target()->Bind();
1657   }
1658   DecrementLoopNesting();
1659 }
1660
1661
1662 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
1663   ASSERT(!in_spilled_code());
1664   VirtualFrame::SpilledScope spilled_scope;
1665   Comment cmnt(masm_, "[ ForInStatement");
1666   CodeForStatementPosition(node);
1667
1668   JumpTarget primitive;
1669   JumpTarget jsobject;
1670   JumpTarget fixed_array;
1671   JumpTarget entry(JumpTarget::BIDIRECTIONAL);
1672   JumpTarget end_del_check;
1673   JumpTarget exit;
1674
1675   // Get the object to enumerate over (converted to JSObject).
1676   LoadAndSpill(node->enumerable());
1677
1678   // Both SpiderMonkey and kjs ignore null and undefined in contrast
1679   // to the specification.  12.6.4 mandates a call to ToObject.
1680   frame_->EmitPop(rax);
1681
1682   // rax: value to be iterated over
1683   __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
1684   exit.Branch(equal);
1685   __ CompareRoot(rax, Heap::kNullValueRootIndex);
1686   exit.Branch(equal);
1687
1688   // Stack layout in body:
1689   // [iteration counter (smi)] <- slot 0
1690   // [length of array]         <- slot 1
1691   // [FixedArray]              <- slot 2
1692   // [Map or 0]                <- slot 3
1693   // [Object]                  <- slot 4
1694
1695   // Check if enumerable is already a JSObject
1696   // rax: value to be iterated over
1697   Condition is_smi = masm_->CheckSmi(rax);
1698   primitive.Branch(is_smi);
1699   __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
1700   jsobject.Branch(above_equal);
1701
1702   primitive.Bind();
1703   frame_->EmitPush(rax);
1704   frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION, 1);
1705   // function call returns the value in rax, which is where we want it below
1706
1707   jsobject.Bind();
1708   // Get the set of properties (as a FixedArray or Map).
1709   // rax: value to be iterated over
1710   frame_->EmitPush(rax);  // Push the object being iterated over.
1711
1712
1713   // Check cache validity in generated code. This is a fast case for
1714   // the JSObject::IsSimpleEnum cache validity checks. If we cannot
1715   // guarantee cache validity, call the runtime system to check cache
1716   // validity or get the property names in a fixed array.
1717   JumpTarget call_runtime;
1718   JumpTarget loop(JumpTarget::BIDIRECTIONAL);
1719   JumpTarget check_prototype;
1720   JumpTarget use_cache;
1721   __ movq(rcx, rax);
1722   loop.Bind();
1723   // Check that there are no elements.
1724   __ movq(rdx, FieldOperand(rcx, JSObject::kElementsOffset));
1725   __ CompareRoot(rdx, Heap::kEmptyFixedArrayRootIndex);
1726   call_runtime.Branch(not_equal);
1727   // Check that instance descriptors are not empty so that we can
1728   // check for an enum cache.  Leave the map in ebx for the subsequent
1729   // prototype load.
1730   __ movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
1731   __ movq(rdx, FieldOperand(rbx, Map::kInstanceDescriptorsOffset));
1732   __ CompareRoot(rdx, Heap::kEmptyDescriptorArrayRootIndex);
1733   call_runtime.Branch(equal);
1734   // Check that there in an enum cache in the non-empty instance
1735   // descriptors.  This is the case if the next enumeration index
1736   // field does not contain a smi.
1737   __ movq(rdx, FieldOperand(rdx, DescriptorArray::kEnumerationIndexOffset));
1738   is_smi = masm_->CheckSmi(rdx);
1739   call_runtime.Branch(is_smi);
1740   // For all objects but the receiver, check that the cache is empty.
1741   __ cmpq(rcx, rax);
1742   check_prototype.Branch(equal);
1743   __ movq(rdx, FieldOperand(rdx, DescriptorArray::kEnumCacheBridgeCacheOffset));
1744   __ CompareRoot(rdx, Heap::kEmptyFixedArrayRootIndex);
1745   call_runtime.Branch(not_equal);
1746   check_prototype.Bind();
1747   // Load the prototype from the map and loop if non-null.
1748   __ movq(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
1749   __ CompareRoot(rcx, Heap::kNullValueRootIndex);
1750   loop.Branch(not_equal);
1751   // The enum cache is valid.  Load the map of the object being
1752   // iterated over and use the cache for the iteration.
1753   __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset));
1754   use_cache.Jump();
1755
1756   call_runtime.Bind();
1757   // Call the runtime to get the property names for the object.
1758   frame_->EmitPush(rax);  // push the Object (slot 4) for the runtime call
1759   frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1);
1760
1761   // If we got a Map, we can do a fast modification check.
1762   // Otherwise, we got a FixedArray, and we have to do a slow check.
1763   // rax: map or fixed array (result from call to
1764   // Runtime::kGetPropertyNamesFast)
1765   __ movq(rdx, rax);
1766   __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
1767   __ CompareRoot(rcx, Heap::kMetaMapRootIndex);
1768   fixed_array.Branch(not_equal);
1769
1770   use_cache.Bind();
1771   // Get enum cache
1772   // rax: map (either the result from a call to
1773   // Runtime::kGetPropertyNamesFast or has been fetched directly from
1774   // the object)
1775   __ movq(rcx, rax);
1776   __ movq(rcx, FieldOperand(rcx, Map::kInstanceDescriptorsOffset));
1777   // Get the bridge array held in the enumeration index field.
1778   __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset));
1779   // Get the cache from the bridge array.
1780   __ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
1781
1782   frame_->EmitPush(rax);  // <- slot 3
1783   frame_->EmitPush(rdx);  // <- slot 2
1784   __ movl(rax, FieldOperand(rdx, FixedArray::kLengthOffset));
1785   __ Integer32ToSmi(rax, rax);
1786   frame_->EmitPush(rax);  // <- slot 1
1787   frame_->EmitPush(Smi::FromInt(0));  // <- slot 0
1788   entry.Jump();
1789
1790   fixed_array.Bind();
1791   // rax: fixed array (result from call to Runtime::kGetPropertyNamesFast)
1792   frame_->EmitPush(Smi::FromInt(0));  // <- slot 3
1793   frame_->EmitPush(rax);  // <- slot 2
1794
1795   // Push the length of the array and the initial index onto the stack.
1796   __ movl(rax, FieldOperand(rax, FixedArray::kLengthOffset));
1797   __ Integer32ToSmi(rax, rax);
1798   frame_->EmitPush(rax);  // <- slot 1
1799   frame_->EmitPush(Smi::FromInt(0));  // <- slot 0
1800
1801   // Condition.
1802   entry.Bind();
1803   // Grab the current frame's height for the break and continue
1804   // targets only after all the state is pushed on the frame.
1805   node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1806   node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1807
1808   __ movq(rax, frame_->ElementAt(0));  // load the current count
1809   __ SmiCompare(frame_->ElementAt(1), rax);  // compare to the array length
1810   node->break_target()->Branch(below_equal);
1811
1812   // Get the i'th entry of the array.
1813   __ movq(rdx, frame_->ElementAt(2));
1814   SmiIndex index = masm_->SmiToIndex(rbx, rax, kPointerSizeLog2);
1815   __ movq(rbx,
1816           FieldOperand(rdx, index.reg, index.scale, FixedArray::kHeaderSize));
1817
1818   // Get the expected map from the stack or a zero map in the
1819   // permanent slow case rax: current iteration count rbx: i'th entry
1820   // of the enum cache
1821   __ movq(rdx, frame_->ElementAt(3));
1822   // Check if the expected map still matches that of the enumerable.
1823   // If not, we have to filter the key.
1824   // rax: current iteration count
1825   // rbx: i'th entry of the enum cache
1826   // rdx: expected map value
1827   __ movq(rcx, frame_->ElementAt(4));
1828   __ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
1829   __ cmpq(rcx, rdx);
1830   end_del_check.Branch(equal);
1831
1832   // Convert the entry to a string (or null if it isn't a property anymore).
1833   frame_->EmitPush(frame_->ElementAt(4));  // push enumerable
1834   frame_->EmitPush(rbx);  // push entry
1835   frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION, 2);
1836   __ movq(rbx, rax);
1837
1838   // If the property has been removed while iterating, we just skip it.
1839   __ CompareRoot(rbx, Heap::kNullValueRootIndex);
1840   node->continue_target()->Branch(equal);
1841
1842   end_del_check.Bind();
1843   // Store the entry in the 'each' expression and take another spin in the
1844   // loop.  rdx: i'th entry of the enum cache (or string there of)
1845   frame_->EmitPush(rbx);
1846   { Reference each(this, node->each());
1847     // Loading a reference may leave the frame in an unspilled state.
1848     frame_->SpillAll();
1849     if (!each.is_illegal()) {
1850       if (each.size() > 0) {
1851         frame_->EmitPush(frame_->ElementAt(each.size()));
1852         each.SetValue(NOT_CONST_INIT);
1853         frame_->Drop(2);  // Drop the original and the copy of the element.
1854       } else {
1855         // If the reference has size zero then we can use the value below
1856         // the reference as if it were above the reference, instead of pushing
1857         // a new copy of it above the reference.
1858         each.SetValue(NOT_CONST_INIT);
1859         frame_->Drop();  // Drop the original of the element.
1860       }
1861     }
1862   }
1863   // Unloading a reference may leave the frame in an unspilled state.
1864   frame_->SpillAll();
1865
1866   // Body.
1867   CheckStack();  // TODO(1222600): ignore if body contains calls.
1868   VisitAndSpill(node->body());
1869
1870   // Next.  Reestablish a spilled frame in case we are coming here via
1871   // a continue in the body.
1872   node->continue_target()->Bind();
1873   frame_->SpillAll();
1874   frame_->EmitPop(rax);
1875   __ SmiAddConstant(rax, rax, Smi::FromInt(1));
1876   frame_->EmitPush(rax);
1877   entry.Jump();
1878
1879   // Cleanup.  No need to spill because VirtualFrame::Drop is safe for
1880   // any frame.
1881   node->break_target()->Bind();
1882   frame_->Drop(5);
1883
1884   // Exit.
1885   exit.Bind();
1886
1887   node->continue_target()->Unuse();
1888   node->break_target()->Unuse();
1889 }
1890
1891 void CodeGenerator::VisitTryCatchStatement(TryCatchStatement* node) {
1892   ASSERT(!in_spilled_code());
1893   VirtualFrame::SpilledScope spilled_scope;
1894   Comment cmnt(masm_, "[ TryCatchStatement");
1895   CodeForStatementPosition(node);
1896
1897   JumpTarget try_block;
1898   JumpTarget exit;
1899
1900   try_block.Call();
1901   // --- Catch block ---
1902   frame_->EmitPush(rax);
1903
1904   // Store the caught exception in the catch variable.
1905   Variable* catch_var = node->catch_var()->var();
1906   ASSERT(catch_var != NULL && catch_var->slot() != NULL);
1907   StoreToSlot(catch_var->slot(), NOT_CONST_INIT);
1908
1909   // Remove the exception from the stack.
1910   frame_->Drop();
1911
1912   VisitStatementsAndSpill(node->catch_block()->statements());
1913   if (has_valid_frame()) {
1914     exit.Jump();
1915   }
1916
1917
1918   // --- Try block ---
1919   try_block.Bind();
1920
1921   frame_->PushTryHandler(TRY_CATCH_HANDLER);
1922   int handler_height = frame_->height();
1923
1924   // Shadow the jump targets for all escapes from the try block, including
1925   // returns.  During shadowing, the original target is hidden as the
1926   // ShadowTarget and operations on the original actually affect the
1927   // shadowing target.
1928   //
1929   // We should probably try to unify the escaping targets and the return
1930   // target.
1931   int nof_escapes = node->escaping_targets()->length();
1932   List<ShadowTarget*> shadows(1 + nof_escapes);
1933
1934   // Add the shadow target for the function return.
1935   static const int kReturnShadowIndex = 0;
1936   shadows.Add(new ShadowTarget(&function_return_));
1937   bool function_return_was_shadowed = function_return_is_shadowed_;
1938   function_return_is_shadowed_ = true;
1939   ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
1940
1941   // Add the remaining shadow targets.
1942   for (int i = 0; i < nof_escapes; i++) {
1943     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
1944   }
1945
1946   // Generate code for the statements in the try block.
1947   VisitStatementsAndSpill(node->try_block()->statements());
1948
1949   // Stop the introduced shadowing and count the number of required unlinks.
1950   // After shadowing stops, the original targets are unshadowed and the
1951   // ShadowTargets represent the formerly shadowing targets.
1952   bool has_unlinks = false;
1953   for (int i = 0; i < shadows.length(); i++) {
1954     shadows[i]->StopShadowing();
1955     has_unlinks = has_unlinks || shadows[i]->is_linked();
1956   }
1957   function_return_is_shadowed_ = function_return_was_shadowed;
1958
1959   // Get an external reference to the handler address.
1960   ExternalReference handler_address(Top::k_handler_address);
1961
1962   // Make sure that there's nothing left on the stack above the
1963   // handler structure.
1964   if (FLAG_debug_code) {
1965     __ movq(kScratchRegister, handler_address);
1966     __ cmpq(rsp, Operand(kScratchRegister, 0));
1967     __ Assert(equal, "stack pointer should point to top handler");
1968   }
1969
1970   // If we can fall off the end of the try block, unlink from try chain.
1971   if (has_valid_frame()) {
1972     // The next handler address is on top of the frame.  Unlink from
1973     // the handler list and drop the rest of this handler from the
1974     // frame.
1975     ASSERT(StackHandlerConstants::kNextOffset == 0);
1976     __ movq(kScratchRegister, handler_address);
1977     frame_->EmitPop(Operand(kScratchRegister, 0));
1978     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
1979     if (has_unlinks) {
1980       exit.Jump();
1981     }
1982   }
1983
1984   // Generate unlink code for the (formerly) shadowing targets that
1985   // have been jumped to.  Deallocate each shadow target.
1986   Result return_value;
1987   for (int i = 0; i < shadows.length(); i++) {
1988     if (shadows[i]->is_linked()) {
1989       // Unlink from try chain; be careful not to destroy the TOS if
1990       // there is one.
1991       if (i == kReturnShadowIndex) {
1992         shadows[i]->Bind(&return_value);
1993         return_value.ToRegister(rax);
1994       } else {
1995         shadows[i]->Bind();
1996       }
1997       // Because we can be jumping here (to spilled code) from
1998       // unspilled code, we need to reestablish a spilled frame at
1999       // this block.
2000       frame_->SpillAll();
2001
2002       // Reload sp from the top handler, because some statements that we
2003       // break from (eg, for...in) may have left stuff on the stack.
2004       __ movq(kScratchRegister, handler_address);
2005       __ movq(rsp, Operand(kScratchRegister, 0));
2006       frame_->Forget(frame_->height() - handler_height);
2007
2008       ASSERT(StackHandlerConstants::kNextOffset == 0);
2009       __ movq(kScratchRegister, handler_address);
2010       frame_->EmitPop(Operand(kScratchRegister, 0));
2011       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2012
2013       if (i == kReturnShadowIndex) {
2014         if (!function_return_is_shadowed_) frame_->PrepareForReturn();
2015         shadows[i]->other_target()->Jump(&return_value);
2016       } else {
2017         shadows[i]->other_target()->Jump();
2018       }
2019     }
2020   }
2021
2022   exit.Bind();
2023 }
2024
2025
2026 void CodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* node) {
2027   ASSERT(!in_spilled_code());
2028   VirtualFrame::SpilledScope spilled_scope;
2029   Comment cmnt(masm_, "[ TryFinallyStatement");
2030   CodeForStatementPosition(node);
2031
2032   // State: Used to keep track of reason for entering the finally
2033   // block. Should probably be extended to hold information for
2034   // break/continue from within the try block.
2035   enum { FALLING, THROWING, JUMPING };
2036
2037   JumpTarget try_block;
2038   JumpTarget finally_block;
2039
2040   try_block.Call();
2041
2042   frame_->EmitPush(rax);
2043   // In case of thrown exceptions, this is where we continue.
2044   __ Move(rcx, Smi::FromInt(THROWING));
2045   finally_block.Jump();
2046
2047   // --- Try block ---
2048   try_block.Bind();
2049
2050   frame_->PushTryHandler(TRY_FINALLY_HANDLER);
2051   int handler_height = frame_->height();
2052
2053   // Shadow the jump targets for all escapes from the try block, including
2054   // returns.  During shadowing, the original target is hidden as the
2055   // ShadowTarget and operations on the original actually affect the
2056   // shadowing target.
2057   //
2058   // We should probably try to unify the escaping targets and the return
2059   // target.
2060   int nof_escapes = node->escaping_targets()->length();
2061   List<ShadowTarget*> shadows(1 + nof_escapes);
2062
2063   // Add the shadow target for the function return.
2064   static const int kReturnShadowIndex = 0;
2065   shadows.Add(new ShadowTarget(&function_return_));
2066   bool function_return_was_shadowed = function_return_is_shadowed_;
2067   function_return_is_shadowed_ = true;
2068   ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
2069
2070   // Add the remaining shadow targets.
2071   for (int i = 0; i < nof_escapes; i++) {
2072     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2073   }
2074
2075   // Generate code for the statements in the try block.
2076   VisitStatementsAndSpill(node->try_block()->statements());
2077
2078   // Stop the introduced shadowing and count the number of required unlinks.
2079   // After shadowing stops, the original targets are unshadowed and the
2080   // ShadowTargets represent the formerly shadowing targets.
2081   int nof_unlinks = 0;
2082   for (int i = 0; i < shadows.length(); i++) {
2083     shadows[i]->StopShadowing();
2084     if (shadows[i]->is_linked()) nof_unlinks++;
2085   }
2086   function_return_is_shadowed_ = function_return_was_shadowed;
2087
2088   // Get an external reference to the handler address.
2089   ExternalReference handler_address(Top::k_handler_address);
2090
2091   // If we can fall off the end of the try block, unlink from the try
2092   // chain and set the state on the frame to FALLING.
2093   if (has_valid_frame()) {
2094     // The next handler address is on top of the frame.
2095     ASSERT(StackHandlerConstants::kNextOffset == 0);
2096     __ movq(kScratchRegister, handler_address);
2097     frame_->EmitPop(Operand(kScratchRegister, 0));
2098     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2099
2100     // Fake a top of stack value (unneeded when FALLING) and set the
2101     // state in ecx, then jump around the unlink blocks if any.
2102     frame_->EmitPush(Heap::kUndefinedValueRootIndex);
2103     __ Move(rcx, Smi::FromInt(FALLING));
2104     if (nof_unlinks > 0) {
2105       finally_block.Jump();
2106     }
2107   }
2108
2109   // Generate code to unlink and set the state for the (formerly)
2110   // shadowing targets that have been jumped to.
2111   for (int i = 0; i < shadows.length(); i++) {
2112     if (shadows[i]->is_linked()) {
2113       // If we have come from the shadowed return, the return value is
2114       // on the virtual frame.  We must preserve it until it is
2115       // pushed.
2116       if (i == kReturnShadowIndex) {
2117         Result return_value;
2118         shadows[i]->Bind(&return_value);
2119         return_value.ToRegister(rax);
2120       } else {
2121         shadows[i]->Bind();
2122       }
2123       // Because we can be jumping here (to spilled code) from
2124       // unspilled code, we need to reestablish a spilled frame at
2125       // this block.
2126       frame_->SpillAll();
2127
2128       // Reload sp from the top handler, because some statements that
2129       // we break from (eg, for...in) may have left stuff on the
2130       // stack.
2131       __ movq(kScratchRegister, handler_address);
2132       __ movq(rsp, Operand(kScratchRegister, 0));
2133       frame_->Forget(frame_->height() - handler_height);
2134
2135       // Unlink this handler and drop it from the frame.
2136       ASSERT(StackHandlerConstants::kNextOffset == 0);
2137       __ movq(kScratchRegister, handler_address);
2138       frame_->EmitPop(Operand(kScratchRegister, 0));
2139       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2140
2141       if (i == kReturnShadowIndex) {
2142         // If this target shadowed the function return, materialize
2143         // the return value on the stack.
2144         frame_->EmitPush(rax);
2145       } else {
2146         // Fake TOS for targets that shadowed breaks and continues.
2147         frame_->EmitPush(Heap::kUndefinedValueRootIndex);
2148       }
2149       __ Move(rcx, Smi::FromInt(JUMPING + i));
2150       if (--nof_unlinks > 0) {
2151         // If this is not the last unlink block, jump around the next.
2152         finally_block.Jump();
2153       }
2154     }
2155   }
2156
2157   // --- Finally block ---
2158   finally_block.Bind();
2159
2160   // Push the state on the stack.
2161   frame_->EmitPush(rcx);
2162
2163   // We keep two elements on the stack - the (possibly faked) result
2164   // and the state - while evaluating the finally block.
2165   //
2166   // Generate code for the statements in the finally block.
2167   VisitStatementsAndSpill(node->finally_block()->statements());
2168
2169   if (has_valid_frame()) {
2170     // Restore state and return value or faked TOS.
2171     frame_->EmitPop(rcx);
2172     frame_->EmitPop(rax);
2173   }
2174
2175   // Generate code to jump to the right destination for all used
2176   // formerly shadowing targets.  Deallocate each shadow target.
2177   for (int i = 0; i < shadows.length(); i++) {
2178     if (has_valid_frame() && shadows[i]->is_bound()) {
2179       BreakTarget* original = shadows[i]->other_target();
2180       __ SmiCompare(rcx, Smi::FromInt(JUMPING + i));
2181       if (i == kReturnShadowIndex) {
2182         // The return value is (already) in rax.
2183         Result return_value = allocator_->Allocate(rax);
2184         ASSERT(return_value.is_valid());
2185         if (function_return_is_shadowed_) {
2186           original->Branch(equal, &return_value);
2187         } else {
2188           // Branch around the preparation for return which may emit
2189           // code.
2190           JumpTarget skip;
2191           skip.Branch(not_equal);
2192           frame_->PrepareForReturn();
2193           original->Jump(&return_value);
2194           skip.Bind();
2195         }
2196       } else {
2197         original->Branch(equal);
2198       }
2199     }
2200   }
2201
2202   if (has_valid_frame()) {
2203     // Check if we need to rethrow the exception.
2204     JumpTarget exit;
2205     __ SmiCompare(rcx, Smi::FromInt(THROWING));
2206     exit.Branch(not_equal);
2207
2208     // Rethrow exception.
2209     frame_->EmitPush(rax);  // undo pop from above
2210     frame_->CallRuntime(Runtime::kReThrow, 1);
2211
2212     // Done.
2213     exit.Bind();
2214   }
2215 }
2216
2217
2218 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2219   ASSERT(!in_spilled_code());
2220   Comment cmnt(masm_, "[ DebuggerStatement");
2221   CodeForStatementPosition(node);
2222 #ifdef ENABLE_DEBUGGER_SUPPORT
2223   // Spill everything, even constants, to the frame.
2224   frame_->SpillAll();
2225
2226   frame_->DebugBreak();
2227   // Ignore the return value.
2228 #endif
2229 }
2230
2231
2232 void CodeGenerator::InstantiateFunction(
2233     Handle<SharedFunctionInfo> function_info) {
2234   // The inevitable call will sync frame elements to memory anyway, so
2235   // we do it eagerly to allow us to push the arguments directly into
2236   // place.
2237   frame_->SyncRange(0, frame_->element_count() - 1);
2238
2239   // Use the fast case closure allocation code that allocates in new
2240   // space for nested functions that don't need literals cloning.
2241   if (scope()->is_function_scope() && function_info->num_literals() == 0) {
2242     FastNewClosureStub stub;
2243     frame_->Push(function_info);
2244     Result answer = frame_->CallStub(&stub, 1);
2245     frame_->Push(&answer);
2246   } else {
2247     // Call the runtime to instantiate the function boilerplate
2248     // object.
2249     frame_->EmitPush(rsi);
2250     frame_->EmitPush(function_info);
2251     Result result = frame_->CallRuntime(Runtime::kNewClosure, 2);
2252     frame_->Push(&result);
2253   }
2254 }
2255
2256
2257 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
2258   Comment cmnt(masm_, "[ FunctionLiteral");
2259
2260   // Build the function info and instantiate it.
2261   Handle<SharedFunctionInfo> function_info =
2262       Compiler::BuildFunctionInfo(node, script(), this);
2263   // Check for stack-overflow exception.
2264   if (HasStackOverflow()) return;
2265   InstantiateFunction(function_info);
2266 }
2267
2268
2269 void CodeGenerator::VisitSharedFunctionInfoLiteral(
2270     SharedFunctionInfoLiteral* node) {
2271   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
2272   InstantiateFunction(node->shared_function_info());
2273 }
2274
2275
2276 void CodeGenerator::VisitConditional(Conditional* node) {
2277   Comment cmnt(masm_, "[ Conditional");
2278   JumpTarget then;
2279   JumpTarget else_;
2280   JumpTarget exit;
2281   ControlDestination dest(&then, &else_, true);
2282   LoadCondition(node->condition(), &dest, true);
2283
2284   if (dest.false_was_fall_through()) {
2285     // The else target was bound, so we compile the else part first.
2286     Load(node->else_expression());
2287
2288     if (then.is_linked()) {
2289       exit.Jump();
2290       then.Bind();
2291       Load(node->then_expression());
2292     }
2293   } else {
2294     // The then target was bound, so we compile the then part first.
2295     Load(node->then_expression());
2296
2297     if (else_.is_linked()) {
2298       exit.Jump();
2299       else_.Bind();
2300       Load(node->else_expression());
2301     }
2302   }
2303
2304   exit.Bind();
2305 }
2306
2307
2308 void CodeGenerator::VisitSlot(Slot* node) {
2309   Comment cmnt(masm_, "[ Slot");
2310   LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF);
2311 }
2312
2313
2314 void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
2315   Comment cmnt(masm_, "[ VariableProxy");
2316   Variable* var = node->var();
2317   Expression* expr = var->rewrite();
2318   if (expr != NULL) {
2319     Visit(expr);
2320   } else {
2321     ASSERT(var->is_global());
2322     Reference ref(this, node);
2323     ref.GetValue();
2324   }
2325 }
2326
2327
2328 void CodeGenerator::VisitLiteral(Literal* node) {
2329   Comment cmnt(masm_, "[ Literal");
2330   frame_->Push(node->handle());
2331 }
2332
2333
2334 // Materialize the regexp literal 'node' in the literals array
2335 // 'literals' of the function.  Leave the regexp boilerplate in
2336 // 'boilerplate'.
2337 class DeferredRegExpLiteral: public DeferredCode {
2338  public:
2339   DeferredRegExpLiteral(Register boilerplate,
2340                         Register literals,
2341                         RegExpLiteral* node)
2342       : boilerplate_(boilerplate), literals_(literals), node_(node) {
2343     set_comment("[ DeferredRegExpLiteral");
2344   }
2345
2346   void Generate();
2347
2348  private:
2349   Register boilerplate_;
2350   Register literals_;
2351   RegExpLiteral* node_;
2352 };
2353
2354
2355 void DeferredRegExpLiteral::Generate() {
2356   // Since the entry is undefined we call the runtime system to
2357   // compute the literal.
2358   // Literal array (0).
2359   __ push(literals_);
2360   // Literal index (1).
2361   __ Push(Smi::FromInt(node_->literal_index()));
2362   // RegExp pattern (2).
2363   __ Push(node_->pattern());
2364   // RegExp flags (3).
2365   __ Push(node_->flags());
2366   __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
2367   if (!boilerplate_.is(rax)) __ movq(boilerplate_, rax);
2368 }
2369
2370
2371 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
2372   Comment cmnt(masm_, "[ RegExp Literal");
2373
2374   // Retrieve the literals array and check the allocated entry.  Begin
2375   // with a writable copy of the function of this activation in a
2376   // register.
2377   frame_->PushFunction();
2378   Result literals = frame_->Pop();
2379   literals.ToRegister();
2380   frame_->Spill(literals.reg());
2381
2382   // Load the literals array of the function.
2383   __ movq(literals.reg(),
2384           FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
2385
2386   // Load the literal at the ast saved index.
2387   Result boilerplate = allocator_->Allocate();
2388   ASSERT(boilerplate.is_valid());
2389   int literal_offset =
2390       FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2391   __ movq(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset));
2392
2393   // Check whether we need to materialize the RegExp object.  If so,
2394   // jump to the deferred code passing the literals array.
2395   DeferredRegExpLiteral* deferred =
2396       new DeferredRegExpLiteral(boilerplate.reg(), literals.reg(), node);
2397   __ CompareRoot(boilerplate.reg(), Heap::kUndefinedValueRootIndex);
2398   deferred->Branch(equal);
2399   deferred->BindExit();
2400   literals.Unuse();
2401
2402   // Push the boilerplate object.
2403   frame_->Push(&boilerplate);
2404 }
2405
2406
2407 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
2408   Comment cmnt(masm_, "[ ObjectLiteral");
2409
2410   // Load a writable copy of the function of this activation in a
2411   // register.
2412   frame_->PushFunction();
2413   Result literals = frame_->Pop();
2414   literals.ToRegister();
2415   frame_->Spill(literals.reg());
2416
2417   // Load the literals array of the function.
2418   __ movq(literals.reg(),
2419           FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
2420   // Literal array.
2421   frame_->Push(&literals);
2422   // Literal index.
2423   frame_->Push(Smi::FromInt(node->literal_index()));
2424   // Constant properties.
2425   frame_->Push(node->constant_properties());
2426   // Should the object literal have fast elements?
2427   frame_->Push(Smi::FromInt(node->fast_elements() ? 1 : 0));
2428   Result clone;
2429   if (node->depth() > 1) {
2430     clone = frame_->CallRuntime(Runtime::kCreateObjectLiteral, 4);
2431   } else {
2432     clone = frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 4);
2433   }
2434   frame_->Push(&clone);
2435
2436   for (int i = 0; i < node->properties()->length(); i++) {
2437     ObjectLiteral::Property* property = node->properties()->at(i);
2438     switch (property->kind()) {
2439       case ObjectLiteral::Property::CONSTANT:
2440         break;
2441       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2442         if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
2443         // else fall through.
2444       case ObjectLiteral::Property::COMPUTED: {
2445         Handle<Object> key(property->key()->handle());
2446         if (key->IsSymbol()) {
2447           // Duplicate the object as the IC receiver.
2448           frame_->Dup();
2449           Load(property->value());
2450           frame_->Push(key);
2451           Result ignored = frame_->CallStoreIC();
2452           break;
2453         }
2454         // Fall through
2455       }
2456       case ObjectLiteral::Property::PROTOTYPE: {
2457         // Duplicate the object as an argument to the runtime call.
2458         frame_->Dup();
2459         Load(property->key());
2460         Load(property->value());
2461         Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
2462         // Ignore the result.
2463         break;
2464       }
2465       case ObjectLiteral::Property::SETTER: {
2466         // Duplicate the object as an argument to the runtime call.
2467         frame_->Dup();
2468         Load(property->key());
2469         frame_->Push(Smi::FromInt(1));
2470         Load(property->value());
2471         Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2472         // Ignore the result.
2473         break;
2474       }
2475       case ObjectLiteral::Property::GETTER: {
2476         // Duplicate the object as an argument to the runtime call.
2477         frame_->Dup();
2478         Load(property->key());
2479         frame_->Push(Smi::FromInt(0));
2480         Load(property->value());
2481         Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2482         // Ignore the result.
2483         break;
2484       }
2485       default: UNREACHABLE();
2486     }
2487   }
2488 }
2489
2490
2491 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2492   Comment cmnt(masm_, "[ ArrayLiteral");
2493
2494   // Load a writable copy of the function of this activation in a
2495   // register.
2496   frame_->PushFunction();
2497   Result literals = frame_->Pop();
2498   literals.ToRegister();
2499   frame_->Spill(literals.reg());
2500
2501   // Load the literals array of the function.
2502   __ movq(literals.reg(),
2503           FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
2504
2505   frame_->Push(&literals);
2506   frame_->Push(Smi::FromInt(node->literal_index()));
2507   frame_->Push(node->constant_elements());
2508   int length = node->values()->length();
2509   Result clone;
2510   if (node->depth() > 1) {
2511     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
2512   } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
2513     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
2514   } else {
2515     FastCloneShallowArrayStub stub(length);
2516     clone = frame_->CallStub(&stub, 3);
2517   }
2518   frame_->Push(&clone);
2519
2520   // Generate code to set the elements in the array that are not
2521   // literals.
2522   for (int i = 0; i < node->values()->length(); i++) {
2523     Expression* value = node->values()->at(i);
2524
2525     // If value is a literal the property value is already set in the
2526     // boilerplate object.
2527     if (value->AsLiteral() != NULL) continue;
2528     // If value is a materialized literal the property value is already set
2529     // in the boilerplate object if it is simple.
2530     if (CompileTimeValue::IsCompileTimeValue(value)) continue;
2531
2532     // The property must be set by generated code.
2533     Load(value);
2534
2535     // Get the property value off the stack.
2536     Result prop_value = frame_->Pop();
2537     prop_value.ToRegister();
2538
2539     // Fetch the array literal while leaving a copy on the stack and
2540     // use it to get the elements array.
2541     frame_->Dup();
2542     Result elements = frame_->Pop();
2543     elements.ToRegister();
2544     frame_->Spill(elements.reg());
2545     // Get the elements FixedArray.
2546     __ movq(elements.reg(),
2547             FieldOperand(elements.reg(), JSObject::kElementsOffset));
2548
2549     // Write to the indexed properties array.
2550     int offset = i * kPointerSize + FixedArray::kHeaderSize;
2551     __ movq(FieldOperand(elements.reg(), offset), prop_value.reg());
2552
2553     // Update the write barrier for the array address.
2554     frame_->Spill(prop_value.reg());  // Overwritten by the write barrier.
2555     Result scratch = allocator_->Allocate();
2556     ASSERT(scratch.is_valid());
2557     __ RecordWrite(elements.reg(), offset, prop_value.reg(), scratch.reg());
2558   }
2559 }
2560
2561
2562 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
2563   ASSERT(!in_spilled_code());
2564   // Call runtime routine to allocate the catch extension object and
2565   // assign the exception value to the catch variable.
2566   Comment cmnt(masm_, "[ CatchExtensionObject");
2567   Load(node->key());
2568   Load(node->value());
2569   Result result =
2570       frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
2571   frame_->Push(&result);
2572 }
2573
2574
2575 void CodeGenerator::VisitAssignment(Assignment* node) {
2576   Comment cmnt(masm_, "[ Assignment");
2577
2578   { Reference target(this, node->target(), node->is_compound());
2579     if (target.is_illegal()) {
2580       // Fool the virtual frame into thinking that we left the assignment's
2581       // value on the frame.
2582       frame_->Push(Smi::FromInt(0));
2583       return;
2584     }
2585     Variable* var = node->target()->AsVariableProxy()->AsVariable();
2586
2587     if (node->starts_initialization_block()) {
2588       ASSERT(target.type() == Reference::NAMED ||
2589              target.type() == Reference::KEYED);
2590       // Change to slow case in the beginning of an initialization
2591       // block to avoid the quadratic behavior of repeatedly adding
2592       // fast properties.
2593
2594       // The receiver is the argument to the runtime call.  It is the
2595       // first value pushed when the reference was loaded to the
2596       // frame.
2597       frame_->PushElementAt(target.size() - 1);
2598       Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
2599     }
2600     if (node->ends_initialization_block()) {
2601       // Add an extra copy of the receiver to the frame, so that it can be
2602       // converted back to fast case after the assignment.
2603       ASSERT(target.type() == Reference::NAMED ||
2604              target.type() == Reference::KEYED);
2605       if (target.type() == Reference::NAMED) {
2606         frame_->Dup();
2607         // Dup target receiver on stack.
2608       } else {
2609         ASSERT(target.type() == Reference::KEYED);
2610         Result temp = frame_->Pop();
2611         frame_->Dup();
2612         frame_->Push(&temp);
2613       }
2614     }
2615     if (node->op() == Token::ASSIGN ||
2616         node->op() == Token::INIT_VAR ||
2617         node->op() == Token::INIT_CONST) {
2618       Load(node->value());
2619
2620     } else {  // Assignment is a compound assignment.
2621       Literal* literal = node->value()->AsLiteral();
2622       bool overwrite_value =
2623           (node->value()->AsBinaryOperation() != NULL &&
2624            node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
2625       Variable* right_var = node->value()->AsVariableProxy()->AsVariable();
2626       // There are two cases where the target is not read in the right hand
2627       // side, that are easy to test for: the right hand side is a literal,
2628       // or the right hand side is a different variable.  TakeValue invalidates
2629       // the target, with an implicit promise that it will be written to again
2630       // before it is read.
2631       if (literal != NULL || (right_var != NULL && right_var != var)) {
2632         target.TakeValue();
2633       } else {
2634         target.GetValue();
2635       }
2636       Load(node->value());
2637       GenericBinaryOperation(node->binary_op(),
2638                              node->type(),
2639                              overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
2640     }
2641
2642     if (var != NULL &&
2643         var->mode() == Variable::CONST &&
2644         node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2645       // Assignment ignored - leave the value on the stack.
2646       UnloadReference(&target);
2647     } else {
2648       CodeForSourcePosition(node->position());
2649       if (node->op() == Token::INIT_CONST) {
2650         // Dynamic constant initializations must use the function context
2651         // and initialize the actual constant declared. Dynamic variable
2652         // initializations are simply assignments and use SetValue.
2653         target.SetValue(CONST_INIT);
2654       } else {
2655         target.SetValue(NOT_CONST_INIT);
2656       }
2657       if (node->ends_initialization_block()) {
2658         ASSERT(target.type() == Reference::UNLOADED);
2659         // End of initialization block. Revert to fast case.  The
2660         // argument to the runtime call is the extra copy of the receiver,
2661         // which is below the value of the assignment.
2662         // Swap the receiver and the value of the assignment expression.
2663         Result lhs = frame_->Pop();
2664         Result receiver = frame_->Pop();
2665         frame_->Push(&lhs);
2666         frame_->Push(&receiver);
2667         Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
2668       }
2669     }
2670   }
2671 }
2672
2673
2674 void CodeGenerator::VisitThrow(Throw* node) {
2675   Comment cmnt(masm_, "[ Throw");
2676   Load(node->exception());
2677   Result result = frame_->CallRuntime(Runtime::kThrow, 1);
2678   frame_->Push(&result);
2679 }
2680
2681
2682 void CodeGenerator::VisitProperty(Property* node) {
2683   Comment cmnt(masm_, "[ Property");
2684   Reference property(this, node);
2685   property.GetValue();
2686 }
2687
2688
2689 void CodeGenerator::VisitCall(Call* node) {
2690   Comment cmnt(masm_, "[ Call");
2691
2692   ZoneList<Expression*>* args = node->arguments();
2693
2694   // Check if the function is a variable or a property.
2695   Expression* function = node->expression();
2696   Variable* var = function->AsVariableProxy()->AsVariable();
2697   Property* property = function->AsProperty();
2698
2699   // ------------------------------------------------------------------------
2700   // Fast-case: Use inline caching.
2701   // ---
2702   // According to ECMA-262, section 11.2.3, page 44, the function to call
2703   // must be resolved after the arguments have been evaluated. The IC code
2704   // automatically handles this by loading the arguments before the function
2705   // is resolved in cache misses (this also holds for megamorphic calls).
2706   // ------------------------------------------------------------------------
2707
2708   if (var != NULL && var->is_possibly_eval()) {
2709     // ----------------------------------
2710     // JavaScript example: 'eval(arg)'  // eval is not known to be shadowed
2711     // ----------------------------------
2712
2713     // In a call to eval, we first call %ResolvePossiblyDirectEval to
2714     // resolve the function we need to call and the receiver of the
2715     // call.  Then we call the resolved function using the given
2716     // arguments.
2717
2718     // Prepare the stack for the call to the resolved function.
2719     Load(function);
2720
2721     // Allocate a frame slot for the receiver.
2722     frame_->Push(Factory::undefined_value());
2723     int arg_count = args->length();
2724     for (int i = 0; i < arg_count; i++) {
2725       Load(args->at(i));
2726     }
2727
2728     // Prepare the stack for the call to ResolvePossiblyDirectEval.
2729     frame_->PushElementAt(arg_count + 1);
2730     if (arg_count > 0) {
2731       frame_->PushElementAt(arg_count);
2732     } else {
2733       frame_->Push(Factory::undefined_value());
2734     }
2735
2736     // Push the receiver.
2737     frame_->PushParameterAt(-1);
2738
2739     // Resolve the call.
2740     Result result =
2741         frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
2742
2743     // The runtime call returns a pair of values in rax (function) and
2744     // rdx (receiver). Touch up the stack with the right values.
2745     Result receiver = allocator_->Allocate(rdx);
2746     frame_->SetElementAt(arg_count + 1, &result);
2747     frame_->SetElementAt(arg_count, &receiver);
2748     receiver.Unuse();
2749
2750     // Call the function.
2751     CodeForSourcePosition(node->position());
2752     InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
2753     CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
2754     result = frame_->CallStub(&call_function, arg_count + 1);
2755
2756     // Restore the context and overwrite the function on the stack with
2757     // the result.
2758     frame_->RestoreContextRegister();
2759     frame_->SetElementAt(0, &result);
2760
2761   } else if (var != NULL && !var->is_this() && var->is_global()) {
2762     // ----------------------------------
2763     // JavaScript example: 'foo(1, 2, 3)'  // foo is global
2764     // ----------------------------------
2765
2766     // Pass the global object as the receiver and let the IC stub
2767     // patch the stack to use the global proxy as 'this' in the
2768     // invoked function.
2769     LoadGlobal();
2770
2771     // Load the arguments.
2772     int arg_count = args->length();
2773     for (int i = 0; i < arg_count; i++) {
2774       Load(args->at(i));
2775     }
2776
2777     // Push the name of the function on the frame.
2778     frame_->Push(var->name());
2779
2780     // Call the IC initialization code.
2781     CodeForSourcePosition(node->position());
2782     Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT,
2783                                        arg_count,
2784                                        loop_nesting());
2785     frame_->RestoreContextRegister();
2786     // Replace the function on the stack with the result.
2787     frame_->Push(&result);
2788
2789   } else if (var != NULL && var->slot() != NULL &&
2790              var->slot()->type() == Slot::LOOKUP) {
2791     // ----------------------------------
2792     // JavaScript example: 'with (obj) foo(1, 2, 3)'  // foo is in obj
2793     // ----------------------------------
2794
2795     // Load the function from the context.  Sync the frame so we can
2796     // push the arguments directly into place.
2797     frame_->SyncRange(0, frame_->element_count() - 1);
2798     frame_->EmitPush(rsi);
2799     frame_->EmitPush(var->name());
2800     frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
2801     // The runtime call returns a pair of values in rax and rdx.  The
2802     // looked-up function is in rax and the receiver is in rdx.  These
2803     // register references are not ref counted here.  We spill them
2804     // eagerly since they are arguments to an inevitable call (and are
2805     // not sharable by the arguments).
2806     ASSERT(!allocator()->is_used(rax));
2807     frame_->EmitPush(rax);
2808
2809     // Load the receiver.
2810     ASSERT(!allocator()->is_used(rdx));
2811     frame_->EmitPush(rdx);
2812
2813     // Call the function.
2814     CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
2815
2816   } else if (property != NULL) {
2817     // Check if the key is a literal string.
2818     Literal* literal = property->key()->AsLiteral();
2819
2820     if (literal != NULL && literal->handle()->IsSymbol()) {
2821       // ------------------------------------------------------------------
2822       // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
2823       // ------------------------------------------------------------------
2824
2825       Handle<String> name = Handle<String>::cast(literal->handle());
2826
2827       if (ArgumentsMode() == LAZY_ARGUMENTS_ALLOCATION &&
2828           name->IsEqualTo(CStrVector("apply")) &&
2829           args->length() == 2 &&
2830           args->at(1)->AsVariableProxy() != NULL &&
2831           args->at(1)->AsVariableProxy()->IsArguments()) {
2832         // Use the optimized Function.prototype.apply that avoids
2833         // allocating lazily allocated arguments objects.
2834         CallApplyLazy(property->obj(),
2835                       args->at(0),
2836                       args->at(1)->AsVariableProxy(),
2837                       node->position());
2838
2839       } else {
2840         // Push the receiver onto the frame.
2841         Load(property->obj());
2842
2843         // Load the arguments.
2844         int arg_count = args->length();
2845         for (int i = 0; i < arg_count; i++) {
2846           Load(args->at(i));
2847         }
2848
2849         // Push the name of the function onto the frame.
2850         frame_->Push(name);
2851
2852         // Call the IC initialization code.
2853         CodeForSourcePosition(node->position());
2854         Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET,
2855                                            arg_count,
2856                                            loop_nesting());
2857         frame_->RestoreContextRegister();
2858         frame_->Push(&result);
2859       }
2860
2861     } else {
2862       // -------------------------------------------
2863       // JavaScript example: 'array[index](1, 2, 3)'
2864       // -------------------------------------------
2865
2866       // Load the function to call from the property through a reference.
2867       if (property->is_synthetic()) {
2868         Reference ref(this, property, false);
2869         ref.GetValue();
2870         // Use global object as receiver.
2871         LoadGlobalReceiver();
2872       } else {
2873         Reference ref(this, property, false);
2874         ASSERT(ref.size() == 2);
2875         Result key = frame_->Pop();
2876         frame_->Dup();  // Duplicate the receiver.
2877         frame_->Push(&key);
2878         ref.GetValue();
2879         // Top of frame contains function to call, with duplicate copy of
2880         // receiver below it.  Swap them.
2881         Result function = frame_->Pop();
2882         Result receiver = frame_->Pop();
2883         frame_->Push(&function);
2884         frame_->Push(&receiver);
2885       }
2886
2887       // Call the function.
2888       CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
2889     }
2890
2891   } else {
2892     // ----------------------------------
2893     // JavaScript example: 'foo(1, 2, 3)'  // foo is not global
2894     // ----------------------------------
2895
2896     // Load the function.
2897     Load(function);
2898
2899     // Pass the global proxy as the receiver.
2900     LoadGlobalReceiver();
2901
2902     // Call the function.
2903     CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
2904   }
2905 }
2906
2907
2908 void CodeGenerator::VisitCallNew(CallNew* node) {
2909   Comment cmnt(masm_, "[ CallNew");
2910
2911   // According to ECMA-262, section 11.2.2, page 44, the function
2912   // expression in new calls must be evaluated before the
2913   // arguments. This is different from ordinary calls, where the
2914   // actual function to call is resolved after the arguments have been
2915   // evaluated.
2916
2917   // Compute function to call and use the global object as the
2918   // receiver. There is no need to use the global proxy here because
2919   // it will always be replaced with a newly allocated object.
2920   Load(node->expression());
2921   LoadGlobal();
2922
2923   // Push the arguments ("left-to-right") on the stack.
2924   ZoneList<Expression*>* args = node->arguments();
2925   int arg_count = args->length();
2926   for (int i = 0; i < arg_count; i++) {
2927     Load(args->at(i));
2928   }
2929
2930   // Call the construct call builtin that handles allocation and
2931   // constructor invocation.
2932   CodeForSourcePosition(node->position());
2933   Result result = frame_->CallConstructor(arg_count);
2934   // Replace the function on the stack with the result.
2935   frame_->SetElementAt(0, &result);
2936 }
2937
2938
2939 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
2940   if (CheckForInlineRuntimeCall(node)) {
2941     return;
2942   }
2943
2944   ZoneList<Expression*>* args = node->arguments();
2945   Comment cmnt(masm_, "[ CallRuntime");
2946   Runtime::Function* function = node->function();
2947
2948   if (function == NULL) {
2949     // Push the builtins object found in the current global object.
2950     Result temp = allocator()->Allocate();
2951     ASSERT(temp.is_valid());
2952     __ movq(temp.reg(), GlobalObject());
2953     __ movq(temp.reg(),
2954             FieldOperand(temp.reg(), GlobalObject::kBuiltinsOffset));
2955     frame_->Push(&temp);
2956   }
2957
2958   // Push the arguments ("left-to-right").
2959   int arg_count = args->length();
2960   for (int i = 0; i < arg_count; i++) {
2961     Load(args->at(i));
2962   }
2963
2964   if (function == NULL) {
2965     // Call the JS runtime function.
2966     frame_->Push(node->name());
2967     Result answer = frame_->CallCallIC(RelocInfo::CODE_TARGET,
2968                                        arg_count,
2969                                        loop_nesting_);
2970     frame_->RestoreContextRegister();
2971     frame_->Push(&answer);
2972   } else {
2973     // Call the C runtime function.
2974     Result answer = frame_->CallRuntime(function, arg_count);
2975     frame_->Push(&answer);
2976   }
2977 }
2978
2979
2980 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
2981   Comment cmnt(masm_, "[ UnaryOperation");
2982
2983   Token::Value op = node->op();
2984
2985   if (op == Token::NOT) {
2986     // Swap the true and false targets but keep the same actual label
2987     // as the fall through.
2988     destination()->Invert();
2989     LoadCondition(node->expression(), destination(), true);
2990     // Swap the labels back.
2991     destination()->Invert();
2992
2993   } else if (op == Token::DELETE) {
2994     Property* property = node->expression()->AsProperty();
2995     if (property != NULL) {
2996       Load(property->obj());
2997       Load(property->key());
2998       Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 2);
2999       frame_->Push(&answer);
3000       return;
3001     }
3002
3003     Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
3004     if (variable != NULL) {
3005       Slot* slot = variable->slot();
3006       if (variable->is_global()) {
3007         LoadGlobal();
3008         frame_->Push(variable->name());
3009         Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
3010                                               CALL_FUNCTION, 2);
3011         frame_->Push(&answer);
3012         return;
3013
3014       } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
3015         // Call the runtime to look up the context holding the named
3016         // variable.  Sync the virtual frame eagerly so we can push the
3017         // arguments directly into place.
3018         frame_->SyncRange(0, frame_->element_count() - 1);
3019         frame_->EmitPush(rsi);
3020         frame_->EmitPush(variable->name());
3021         Result context = frame_->CallRuntime(Runtime::kLookupContext, 2);
3022         ASSERT(context.is_register());
3023         frame_->EmitPush(context.reg());
3024         context.Unuse();
3025         frame_->EmitPush(variable->name());
3026         Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
3027                                               CALL_FUNCTION, 2);
3028         frame_->Push(&answer);
3029         return;
3030       }
3031
3032       // Default: Result of deleting non-global, not dynamically
3033       // introduced variables is false.
3034       frame_->Push(Factory::false_value());
3035
3036     } else {
3037       // Default: Result of deleting expressions is true.
3038       Load(node->expression());  // may have side-effects
3039       frame_->SetElementAt(0, Factory::true_value());
3040     }
3041
3042   } else if (op == Token::TYPEOF) {
3043     // Special case for loading the typeof expression; see comment on
3044     // LoadTypeofExpression().
3045     LoadTypeofExpression(node->expression());
3046     Result answer = frame_->CallRuntime(Runtime::kTypeof, 1);
3047     frame_->Push(&answer);
3048
3049   } else if (op == Token::VOID) {
3050     Expression* expression = node->expression();
3051     if (expression && expression->AsLiteral() && (
3052         expression->AsLiteral()->IsTrue() ||
3053         expression->AsLiteral()->IsFalse() ||
3054         expression->AsLiteral()->handle()->IsNumber() ||
3055         expression->AsLiteral()->handle()->IsString() ||
3056         expression->AsLiteral()->handle()->IsJSRegExp() ||
3057         expression->AsLiteral()->IsNull())) {
3058       // Omit evaluating the value of the primitive literal.
3059       // It will be discarded anyway, and can have no side effect.
3060       frame_->Push(Factory::undefined_value());
3061     } else {
3062       Load(node->expression());
3063       frame_->SetElementAt(0, Factory::undefined_value());
3064     }
3065
3066   } else {
3067     bool overwrite =
3068       (node->expression()->AsBinaryOperation() != NULL &&
3069        node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
3070     Load(node->expression());
3071     switch (op) {
3072       case Token::NOT:
3073       case Token::DELETE:
3074       case Token::TYPEOF:
3075         UNREACHABLE();  // handled above
3076         break;
3077
3078       case Token::SUB: {
3079         GenericUnaryOpStub stub(Token::SUB, overwrite);
3080         Result operand = frame_->Pop();
3081         Result answer = frame_->CallStub(&stub, &operand);
3082         frame_->Push(&answer);
3083         break;
3084       }
3085
3086       case Token::BIT_NOT: {
3087         // Smi check.
3088         JumpTarget smi_label;
3089         JumpTarget continue_label;
3090         Result operand = frame_->Pop();
3091         operand.ToRegister();
3092
3093         Condition is_smi = masm_->CheckSmi(operand.reg());
3094         smi_label.Branch(is_smi, &operand);
3095
3096         GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
3097         Result answer = frame_->CallStub(&stub, &operand);
3098         continue_label.Jump(&answer);
3099
3100         smi_label.Bind(&answer);
3101         answer.ToRegister();
3102         frame_->Spill(answer.reg());
3103         __ SmiNot(answer.reg(), answer.reg());
3104         continue_label.Bind(&answer);
3105         frame_->Push(&answer);
3106         break;
3107       }
3108
3109       case Token::ADD: {
3110         // Smi check.
3111         JumpTarget continue_label;
3112         Result operand = frame_->Pop();
3113         operand.ToRegister();
3114         Condition is_smi = masm_->CheckSmi(operand.reg());
3115         continue_label.Branch(is_smi, &operand);
3116         frame_->Push(&operand);
3117         Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER,
3118                                               CALL_FUNCTION, 1);
3119
3120         continue_label.Bind(&answer);
3121         frame_->Push(&answer);
3122         break;
3123       }
3124
3125       default:
3126         UNREACHABLE();
3127     }
3128   }
3129 }
3130
3131
3132 // The value in dst was optimistically incremented or decremented.  The
3133 // result overflowed or was not smi tagged.  Undo the operation, call
3134 // into the runtime to convert the argument to a number, and call the
3135 // specialized add or subtract stub.  The result is left in dst.
3136 class DeferredPrefixCountOperation: public DeferredCode {
3137  public:
3138   DeferredPrefixCountOperation(Register dst, bool is_increment)
3139       : dst_(dst), is_increment_(is_increment) {
3140     set_comment("[ DeferredCountOperation");
3141   }
3142
3143   virtual void Generate();
3144
3145  private:
3146   Register dst_;
3147   bool is_increment_;
3148 };
3149
3150
3151 void DeferredPrefixCountOperation::Generate() {
3152   __ push(dst_);
3153   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
3154   __ push(rax);
3155   __ Push(Smi::FromInt(1));
3156   if (is_increment_) {
3157     __ CallRuntime(Runtime::kNumberAdd, 2);
3158   } else {
3159     __ CallRuntime(Runtime::kNumberSub, 2);
3160   }
3161   if (!dst_.is(rax)) __ movq(dst_, rax);
3162 }
3163
3164
3165 // The value in dst was optimistically incremented or decremented.  The
3166 // result overflowed or was not smi tagged.  Undo the operation and call
3167 // into the runtime to convert the argument to a number.  Update the
3168 // original value in old.  Call the specialized add or subtract stub.
3169 // The result is left in dst.
3170 class DeferredPostfixCountOperation: public DeferredCode {
3171  public:
3172   DeferredPostfixCountOperation(Register dst, Register old, bool is_increment)
3173       : dst_(dst), old_(old), is_increment_(is_increment) {
3174     set_comment("[ DeferredCountOperation");
3175   }
3176
3177   virtual void Generate();
3178
3179  private:
3180   Register dst_;
3181   Register old_;
3182   bool is_increment_;
3183 };
3184
3185
3186 void DeferredPostfixCountOperation::Generate() {
3187   __ push(dst_);
3188   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
3189
3190   // Save the result of ToNumber to use as the old value.
3191   __ push(rax);
3192
3193   // Call the runtime for the addition or subtraction.
3194   __ push(rax);
3195   __ Push(Smi::FromInt(1));
3196   if (is_increment_) {
3197     __ CallRuntime(Runtime::kNumberAdd, 2);
3198   } else {
3199     __ CallRuntime(Runtime::kNumberSub, 2);
3200   }
3201   if (!dst_.is(rax)) __ movq(dst_, rax);
3202   __ pop(old_);
3203 }
3204
3205
3206 void CodeGenerator::VisitCountOperation(CountOperation* node) {
3207   Comment cmnt(masm_, "[ CountOperation");
3208
3209   bool is_postfix = node->is_postfix();
3210   bool is_increment = node->op() == Token::INC;
3211
3212   Variable* var = node->expression()->AsVariableProxy()->AsVariable();
3213   bool is_const = (var != NULL && var->mode() == Variable::CONST);
3214
3215   // Postfix operations need a stack slot under the reference to hold
3216   // the old value while the new value is being stored.  This is so that
3217   // in the case that storing the new value requires a call, the old
3218   // value will be in the frame to be spilled.
3219   if (is_postfix) frame_->Push(Smi::FromInt(0));
3220
3221   // A constant reference is not saved to, so the reference is not a
3222   // compound assignment reference.
3223   { Reference target(this, node->expression(), !is_const);
3224     if (target.is_illegal()) {
3225       // Spoof the virtual frame to have the expected height (one higher
3226       // than on entry).
3227       if (!is_postfix) frame_->Push(Smi::FromInt(0));
3228       return;
3229     }
3230     target.TakeValue();
3231
3232     Result new_value = frame_->Pop();
3233     new_value.ToRegister();
3234
3235     Result old_value;  // Only allocated in the postfix case.
3236     if (is_postfix) {
3237       // Allocate a temporary to preserve the old value.
3238       old_value = allocator_->Allocate();
3239       ASSERT(old_value.is_valid());
3240       __ movq(old_value.reg(), new_value.reg());
3241     }
3242     // Ensure the new value is writable.
3243     frame_->Spill(new_value.reg());
3244
3245     DeferredCode* deferred = NULL;
3246     if (is_postfix) {
3247       deferred = new DeferredPostfixCountOperation(new_value.reg(),
3248                                                    old_value.reg(),
3249                                                    is_increment);
3250     } else {
3251       deferred = new DeferredPrefixCountOperation(new_value.reg(),
3252                                                   is_increment);
3253     }
3254
3255     __ JumpIfNotSmi(new_value.reg(), deferred->entry_label());
3256     if (is_increment) {
3257       __ SmiAddConstant(kScratchRegister,
3258                         new_value.reg(),
3259                         Smi::FromInt(1),
3260                         deferred->entry_label());
3261     } else {
3262       __ SmiSubConstant(kScratchRegister,
3263                         new_value.reg(),
3264                         Smi::FromInt(1),
3265                         deferred->entry_label());
3266     }
3267     __ movq(new_value.reg(), kScratchRegister);
3268     deferred->BindExit();
3269
3270     // Postfix: store the old value in the allocated slot under the
3271     // reference.
3272     if (is_postfix) frame_->SetElementAt(target.size(), &old_value);
3273
3274     frame_->Push(&new_value);
3275     // Non-constant: update the reference.
3276     if (!is_const) target.SetValue(NOT_CONST_INIT);
3277   }
3278
3279   // Postfix: drop the new value and use the old.
3280   if (is_postfix) frame_->Drop();
3281 }
3282
3283
3284 void CodeGenerator::GenerateLogicalBooleanOperation(BinaryOperation* node) {
3285   // According to ECMA-262 section 11.11, page 58, the binary logical
3286   // operators must yield the result of one of the two expressions
3287   // before any ToBoolean() conversions. This means that the value
3288   // produced by a && or || operator is not necessarily a boolean.
3289
3290   // NOTE: If the left hand side produces a materialized value (not
3291   // control flow), we force the right hand side to do the same. This
3292   // is necessary because we assume that if we get control flow on the
3293   // last path out of an expression we got it on all paths.
3294   if (node->op() == Token::AND) {
3295     JumpTarget is_true;
3296     ControlDestination dest(&is_true, destination()->false_target(), true);
3297     LoadCondition(node->left(), &dest, false);
3298
3299     if (dest.false_was_fall_through()) {
3300       // The current false target was used as the fall-through.  If
3301       // there are no dangling jumps to is_true then the left
3302       // subexpression was unconditionally false.  Otherwise we have
3303       // paths where we do have to evaluate the right subexpression.
3304       if (is_true.is_linked()) {
3305         // We need to compile the right subexpression.  If the jump to
3306         // the current false target was a forward jump then we have a
3307         // valid frame, we have just bound the false target, and we
3308         // have to jump around the code for the right subexpression.
3309         if (has_valid_frame()) {
3310           destination()->false_target()->Unuse();
3311           destination()->false_target()->Jump();
3312         }
3313         is_true.Bind();
3314         // The left subexpression compiled to control flow, so the
3315         // right one is free to do so as well.
3316         LoadCondition(node->right(), destination(), false);
3317       } else {
3318         // We have actually just jumped to or bound the current false
3319         // target but the current control destination is not marked as
3320         // used.
3321         destination()->Use(false);
3322       }
3323
3324     } else if (dest.is_used()) {
3325       // The left subexpression compiled to control flow (and is_true
3326       // was just bound), so the right is free to do so as well.
3327       LoadCondition(node->right(), destination(), false);
3328
3329     } else {
3330       // We have a materialized value on the frame, so we exit with
3331       // one on all paths.  There are possibly also jumps to is_true
3332       // from nested subexpressions.
3333       JumpTarget pop_and_continue;
3334       JumpTarget exit;
3335
3336       // Avoid popping the result if it converts to 'false' using the
3337       // standard ToBoolean() conversion as described in ECMA-262,
3338       // section 9.2, page 30.
3339       //
3340       // Duplicate the TOS value. The duplicate will be popped by
3341       // ToBoolean.
3342       frame_->Dup();
3343       ControlDestination dest(&pop_and_continue, &exit, true);
3344       ToBoolean(&dest);
3345
3346       // Pop the result of evaluating the first part.
3347       frame_->Drop();
3348
3349       // Compile right side expression.
3350       is_true.Bind();
3351       Load(node->right());
3352
3353       // Exit (always with a materialized value).
3354       exit.Bind();
3355     }
3356
3357   } else {
3358     ASSERT(node->op() == Token::OR);
3359     JumpTarget is_false;
3360     ControlDestination dest(destination()->true_target(), &is_false, false);
3361     LoadCondition(node->left(), &dest, false);
3362
3363     if (dest.true_was_fall_through()) {
3364       // The current true target was used as the fall-through.  If
3365       // there are no dangling jumps to is_false then the left
3366       // subexpression was unconditionally true.  Otherwise we have
3367       // paths where we do have to evaluate the right subexpression.
3368       if (is_false.is_linked()) {
3369         // We need to compile the right subexpression.  If the jump to
3370         // the current true target was a forward jump then we have a
3371         // valid frame, we have just bound the true target, and we
3372         // have to jump around the code for the right subexpression.
3373         if (has_valid_frame()) {
3374           destination()->true_target()->Unuse();
3375           destination()->true_target()->Jump();
3376         }
3377         is_false.Bind();
3378         // The left subexpression compiled to control flow, so the
3379         // right one is free to do so as well.
3380         LoadCondition(node->right(), destination(), false);
3381       } else {
3382         // We have just jumped to or bound the current true target but
3383         // the current control destination is not marked as used.
3384         destination()->Use(true);
3385       }
3386
3387     } else if (dest.is_used()) {
3388       // The left subexpression compiled to control flow (and is_false
3389       // was just bound), so the right is free to do so as well.
3390       LoadCondition(node->right(), destination(), false);
3391
3392     } else {
3393       // We have a materialized value on the frame, so we exit with
3394       // one on all paths.  There are possibly also jumps to is_false
3395       // from nested subexpressions.
3396       JumpTarget pop_and_continue;
3397       JumpTarget exit;
3398
3399       // Avoid popping the result if it converts to 'true' using the
3400       // standard ToBoolean() conversion as described in ECMA-262,
3401       // section 9.2, page 30.
3402       //
3403       // Duplicate the TOS value. The duplicate will be popped by
3404       // ToBoolean.
3405       frame_->Dup();
3406       ControlDestination dest(&exit, &pop_and_continue, false);
3407       ToBoolean(&dest);
3408
3409       // Pop the result of evaluating the first part.
3410       frame_->Drop();
3411
3412       // Compile right side expression.
3413       is_false.Bind();
3414       Load(node->right());
3415
3416       // Exit (always with a materialized value).
3417       exit.Bind();
3418     }
3419   }
3420 }
3421
3422 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
3423   Comment cmnt(masm_, "[ BinaryOperation");
3424
3425   if (node->op() == Token::AND || node->op() == Token::OR) {
3426     GenerateLogicalBooleanOperation(node);
3427   } else {
3428     // NOTE: The code below assumes that the slow cases (calls to runtime)
3429     // never return a constant/immutable object.
3430     OverwriteMode overwrite_mode = NO_OVERWRITE;
3431     if (node->left()->AsBinaryOperation() != NULL &&
3432         node->left()->AsBinaryOperation()->ResultOverwriteAllowed()) {
3433       overwrite_mode = OVERWRITE_LEFT;
3434     } else if (node->right()->AsBinaryOperation() != NULL &&
3435                node->right()->AsBinaryOperation()->ResultOverwriteAllowed()) {
3436       overwrite_mode = OVERWRITE_RIGHT;
3437     }
3438
3439     Load(node->left());
3440     Load(node->right());
3441     GenericBinaryOperation(node->op(), node->type(), overwrite_mode);
3442   }
3443 }
3444
3445
3446
3447 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
3448   Comment cmnt(masm_, "[ CompareOperation");
3449
3450   // Get the expressions from the node.
3451   Expression* left = node->left();
3452   Expression* right = node->right();
3453   Token::Value op = node->op();
3454   // To make typeof testing for natives implemented in JavaScript really
3455   // efficient, we generate special code for expressions of the form:
3456   // 'typeof <expression> == <string>'.
3457   UnaryOperation* operation = left->AsUnaryOperation();
3458   if ((op == Token::EQ || op == Token::EQ_STRICT) &&
3459       (operation != NULL && operation->op() == Token::TYPEOF) &&
3460       (right->AsLiteral() != NULL &&
3461        right->AsLiteral()->handle()->IsString())) {
3462     Handle<String> check(Handle<String>::cast(right->AsLiteral()->handle()));
3463
3464     // Load the operand and move it to a register.
3465     LoadTypeofExpression(operation->expression());
3466     Result answer = frame_->Pop();
3467     answer.ToRegister();
3468
3469     if (check->Equals(Heap::number_symbol())) {
3470       Condition is_smi = masm_->CheckSmi(answer.reg());
3471       destination()->true_target()->Branch(is_smi);
3472       frame_->Spill(answer.reg());
3473       __ movq(answer.reg(), FieldOperand(answer.reg(), HeapObject::kMapOffset));
3474       __ CompareRoot(answer.reg(), Heap::kHeapNumberMapRootIndex);
3475       answer.Unuse();
3476       destination()->Split(equal);
3477
3478     } else if (check->Equals(Heap::string_symbol())) {
3479       Condition is_smi = masm_->CheckSmi(answer.reg());
3480       destination()->false_target()->Branch(is_smi);
3481
3482       // It can be an undetectable string object.
3483       __ movq(kScratchRegister,
3484               FieldOperand(answer.reg(), HeapObject::kMapOffset));
3485       __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
3486                Immediate(1 << Map::kIsUndetectable));
3487       destination()->false_target()->Branch(not_zero);
3488       __ CmpInstanceType(kScratchRegister, FIRST_NONSTRING_TYPE);
3489       answer.Unuse();
3490       destination()->Split(below);  // Unsigned byte comparison needed.
3491
3492     } else if (check->Equals(Heap::boolean_symbol())) {
3493       __ CompareRoot(answer.reg(), Heap::kTrueValueRootIndex);
3494       destination()->true_target()->Branch(equal);
3495       __ CompareRoot(answer.reg(), Heap::kFalseValueRootIndex);
3496       answer.Unuse();
3497       destination()->Split(equal);
3498
3499     } else if (check->Equals(Heap::undefined_symbol())) {
3500       __ CompareRoot(answer.reg(), Heap::kUndefinedValueRootIndex);
3501       destination()->true_target()->Branch(equal);
3502
3503       Condition is_smi = masm_->CheckSmi(answer.reg());
3504       destination()->false_target()->Branch(is_smi);
3505
3506       // It can be an undetectable object.
3507       __ movq(kScratchRegister,
3508               FieldOperand(answer.reg(), HeapObject::kMapOffset));
3509       __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
3510                Immediate(1 << Map::kIsUndetectable));
3511       answer.Unuse();
3512       destination()->Split(not_zero);
3513
3514     } else if (check->Equals(Heap::function_symbol())) {
3515       Condition is_smi = masm_->CheckSmi(answer.reg());
3516       destination()->false_target()->Branch(is_smi);
3517       frame_->Spill(answer.reg());
3518       __ CmpObjectType(answer.reg(), JS_FUNCTION_TYPE, answer.reg());
3519       destination()->true_target()->Branch(equal);
3520       // Regular expressions are callable so typeof == 'function'.
3521       __ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE);
3522       answer.Unuse();
3523       destination()->Split(equal);
3524
3525     } else if (check->Equals(Heap::object_symbol())) {
3526       Condition is_smi = masm_->CheckSmi(answer.reg());
3527       destination()->false_target()->Branch(is_smi);
3528       __ CompareRoot(answer.reg(), Heap::kNullValueRootIndex);
3529       destination()->true_target()->Branch(equal);
3530
3531       // Regular expressions are typeof == 'function', not 'object'.
3532       __ CmpObjectType(answer.reg(), JS_REGEXP_TYPE, kScratchRegister);
3533       destination()->false_target()->Branch(equal);
3534
3535       // It can be an undetectable object.
3536       __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
3537                Immediate(1 << Map::kIsUndetectable));
3538       destination()->false_target()->Branch(not_zero);
3539       __ CmpInstanceType(kScratchRegister, FIRST_JS_OBJECT_TYPE);
3540       destination()->false_target()->Branch(below);
3541       __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
3542       answer.Unuse();
3543       destination()->Split(below_equal);
3544     } else {
3545       // Uncommon case: typeof testing against a string literal that is
3546       // never returned from the typeof operator.
3547       answer.Unuse();
3548       destination()->Goto(false);
3549     }
3550     return;
3551   }
3552
3553   Condition cc = no_condition;
3554   bool strict = false;
3555   switch (op) {
3556     case Token::EQ_STRICT:
3557       strict = true;
3558       // Fall through
3559     case Token::EQ:
3560       cc = equal;
3561       break;
3562     case Token::LT:
3563       cc = less;
3564       break;
3565     case Token::GT:
3566       cc = greater;
3567       break;
3568     case Token::LTE:
3569       cc = less_equal;
3570       break;
3571     case Token::GTE:
3572       cc = greater_equal;
3573       break;
3574     case Token::IN: {
3575       Load(left);
3576       Load(right);
3577       Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
3578       frame_->Push(&answer);  // push the result
3579       return;
3580     }
3581     case Token::INSTANCEOF: {
3582       Load(left);
3583       Load(right);
3584       InstanceofStub stub;
3585       Result answer = frame_->CallStub(&stub, 2);
3586       answer.ToRegister();
3587       __ testq(answer.reg(), answer.reg());
3588       answer.Unuse();
3589       destination()->Split(zero);
3590       return;
3591     }
3592     default:
3593       UNREACHABLE();
3594   }
3595   Load(left);
3596   Load(right);
3597   Comparison(node, cc, strict, destination());
3598 }
3599
3600
3601 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
3602   frame_->PushFunction();
3603 }
3604
3605
3606 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
3607   ASSERT(args->length() == 1);
3608
3609   // ArgumentsAccessStub expects the key in rdx and the formal
3610   // parameter count in rax.
3611   Load(args->at(0));
3612   Result key = frame_->Pop();
3613   // Explicitly create a constant result.
3614   Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters())));
3615   // Call the shared stub to get to arguments[key].
3616   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
3617   Result result = frame_->CallStub(&stub, &key, &count);
3618   frame_->Push(&result);
3619 }
3620
3621
3622 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
3623   ASSERT(args->length() == 1);
3624   Load(args->at(0));
3625   Result value = frame_->Pop();
3626   value.ToRegister();
3627   ASSERT(value.is_valid());
3628   Condition is_smi = masm_->CheckSmi(value.reg());
3629   destination()->false_target()->Branch(is_smi);
3630   // It is a heap object - get map.
3631   // Check if the object is a JS array or not.
3632   __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, kScratchRegister);
3633   value.Unuse();
3634   destination()->Split(equal);
3635 }
3636
3637
3638 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
3639   ASSERT(args->length() == 1);
3640   Load(args->at(0));
3641   Result value = frame_->Pop();
3642   value.ToRegister();
3643   ASSERT(value.is_valid());
3644   Condition is_smi = masm_->CheckSmi(value.reg());
3645   destination()->false_target()->Branch(is_smi);
3646   // It is a heap object - get map.
3647   // Check if the object is a regexp.
3648   __ CmpObjectType(value.reg(), JS_REGEXP_TYPE, kScratchRegister);
3649   value.Unuse();
3650   destination()->Split(equal);
3651 }
3652
3653
3654 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
3655   // This generates a fast version of:
3656   // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
3657   ASSERT(args->length() == 1);
3658   Load(args->at(0));
3659   Result obj = frame_->Pop();
3660   obj.ToRegister();
3661   Condition is_smi = masm_->CheckSmi(obj.reg());
3662   destination()->false_target()->Branch(is_smi);
3663
3664   __ Move(kScratchRegister, Factory::null_value());
3665   __ cmpq(obj.reg(), kScratchRegister);
3666   destination()->true_target()->Branch(equal);
3667
3668   __ movq(kScratchRegister, FieldOperand(obj.reg(), HeapObject::kMapOffset));
3669   // Undetectable objects behave like undefined when tested with typeof.
3670   __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
3671           Immediate(1 << Map::kIsUndetectable));
3672   destination()->false_target()->Branch(not_zero);
3673   __ CmpInstanceType(kScratchRegister, FIRST_JS_OBJECT_TYPE);
3674   destination()->false_target()->Branch(less);
3675   __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
3676   obj.Unuse();
3677   destination()->Split(less_equal);
3678 }
3679
3680
3681 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
3682   // This generates a fast version of:
3683   // (%_ClassOf(arg) === 'Function')
3684   ASSERT(args->length() == 1);
3685   Load(args->at(0));
3686   Result obj = frame_->Pop();
3687   obj.ToRegister();
3688   Condition is_smi = masm_->CheckSmi(obj.reg());
3689   destination()->false_target()->Branch(is_smi);
3690   __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, kScratchRegister);
3691   obj.Unuse();
3692   destination()->Split(equal);
3693 }
3694
3695
3696 void CodeGenerator::GenerateIsUndetectableObject(ZoneList<Expression*>* args) {
3697   ASSERT(args->length() == 1);
3698   Load(args->at(0));
3699   Result obj = frame_->Pop();
3700   obj.ToRegister();
3701   Condition is_smi = masm_->CheckSmi(obj.reg());
3702   destination()->false_target()->Branch(is_smi);
3703   __ movq(kScratchRegister, FieldOperand(obj.reg(), HeapObject::kMapOffset));
3704   __ movzxbl(kScratchRegister,
3705              FieldOperand(kScratchRegister, Map::kBitFieldOffset));
3706   __ testl(kScratchRegister, Immediate(1 << Map::kIsUndetectable));
3707   obj.Unuse();
3708   destination()->Split(not_zero);
3709 }
3710
3711
3712 void CodeGenerator::GenerateIsConstructCall(ZoneList<Expression*>* args) {
3713   ASSERT(args->length() == 0);
3714
3715   // Get the frame pointer for the calling frame.
3716   Result fp = allocator()->Allocate();
3717   __ movq(fp.reg(), Operand(rbp, StandardFrameConstants::kCallerFPOffset));
3718
3719   // Skip the arguments adaptor frame if it exists.
3720   Label check_frame_marker;
3721   __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kContextOffset),
3722                 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3723   __ j(not_equal, &check_frame_marker);
3724   __ movq(fp.reg(), Operand(fp.reg(), StandardFrameConstants::kCallerFPOffset));
3725
3726   // Check the marker in the calling frame.
3727   __ bind(&check_frame_marker);
3728   __ SmiCompare(Operand(fp.reg(), StandardFrameConstants::kMarkerOffset),
3729                 Smi::FromInt(StackFrame::CONSTRUCT));
3730   fp.Unuse();
3731   destination()->Split(equal);
3732 }
3733
3734
3735 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
3736   ASSERT(args->length() == 0);
3737   // ArgumentsAccessStub takes the parameter count as an input argument
3738   // in register eax.  Create a constant result for it.
3739   Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters())));
3740   // Call the shared stub to get to the arguments.length.
3741   ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
3742   Result result = frame_->CallStub(&stub, &count);
3743   frame_->Push(&result);
3744 }
3745
3746
3747 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
3748   Comment(masm_, "[ GenerateFastCharCodeAt");
3749   ASSERT(args->length() == 2);
3750
3751   Label slow_case;
3752   Label end;
3753   Label not_a_flat_string;
3754   Label try_again_with_new_string;
3755   Label ascii_string;
3756   Label got_char_code;
3757
3758   Load(args->at(0));
3759   Load(args->at(1));
3760   Result index = frame_->Pop();
3761   Result object = frame_->Pop();
3762
3763   // Get register rcx to use as shift amount later.
3764   Result shift_amount;
3765   if (object.is_register() && object.reg().is(rcx)) {
3766     Result fresh = allocator_->Allocate();
3767     shift_amount = object;
3768     object = fresh;
3769     __ movq(object.reg(), rcx);
3770   }
3771   if (index.is_register() && index.reg().is(rcx)) {
3772     Result fresh = allocator_->Allocate();
3773     shift_amount = index;
3774     index = fresh;
3775     __ movq(index.reg(), rcx);
3776   }
3777   // There could be references to ecx in the frame. Allocating will
3778   // spill them, otherwise spill explicitly.
3779   if (shift_amount.is_valid()) {
3780     frame_->Spill(rcx);
3781   } else {
3782     shift_amount = allocator()->Allocate(rcx);
3783   }
3784   ASSERT(shift_amount.is_register());
3785   ASSERT(shift_amount.reg().is(rcx));
3786   ASSERT(allocator_->count(rcx) == 1);
3787
3788   // We will mutate the index register and possibly the object register.
3789   // The case where they are somehow the same register is handled
3790   // because we only mutate them in the case where the receiver is a
3791   // heap object and the index is not.
3792   object.ToRegister();
3793   index.ToRegister();
3794   frame_->Spill(object.reg());
3795   frame_->Spill(index.reg());
3796
3797   // We need a single extra temporary register.
3798   Result temp = allocator()->Allocate();
3799   ASSERT(temp.is_valid());
3800
3801   // There is no virtual frame effect from here up to the final result
3802   // push.
3803
3804   // If the receiver is a smi trigger the slow case.
3805   __ JumpIfSmi(object.reg(), &slow_case);
3806
3807   // If the index is negative or non-smi trigger the slow case.
3808   __ JumpIfNotPositiveSmi(index.reg(), &slow_case);
3809
3810   // Untag the index.
3811   __ SmiToInteger32(index.reg(), index.reg());
3812
3813   __ bind(&try_again_with_new_string);
3814   // Fetch the instance type of the receiver into rcx.
3815   __ movq(rcx, FieldOperand(object.reg(), HeapObject::kMapOffset));
3816   __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset));
3817   // If the receiver is not a string trigger the slow case.
3818   __ testb(rcx, Immediate(kIsNotStringMask));
3819   __ j(not_zero, &slow_case);
3820
3821   // Check for index out of range.
3822   __ cmpl(index.reg(), FieldOperand(object.reg(), String::kLengthOffset));
3823   __ j(greater_equal, &slow_case);
3824   // Reload the instance type (into the temp register this time)..
3825   __ movq(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
3826   __ movzxbl(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
3827
3828   // We need special handling for non-flat strings.
3829   ASSERT_EQ(0, kSeqStringTag);
3830   __ testb(temp.reg(), Immediate(kStringRepresentationMask));
3831   __ j(not_zero, &not_a_flat_string);
3832   // Check for 1-byte or 2-byte string.
3833   ASSERT_EQ(0, kTwoByteStringTag);
3834   __ testb(temp.reg(), Immediate(kStringEncodingMask));
3835   __ j(not_zero, &ascii_string);
3836
3837   // 2-byte string.
3838   // Load the 2-byte character code into the temp register.
3839   __ movzxwl(temp.reg(), FieldOperand(object.reg(),
3840                                       index.reg(),
3841                                       times_2,
3842                                       SeqTwoByteString::kHeaderSize));
3843   __ jmp(&got_char_code);
3844
3845   // ASCII string.
3846   __ bind(&ascii_string);
3847   // Load the byte into the temp register.
3848   __ movzxbl(temp.reg(), FieldOperand(object.reg(),
3849                                       index.reg(),
3850                                       times_1,
3851                                       SeqAsciiString::kHeaderSize));
3852   __ bind(&got_char_code);
3853   __ Integer32ToSmi(temp.reg(), temp.reg());
3854   __ jmp(&end);
3855
3856   // Handle non-flat strings.
3857   __ bind(&not_a_flat_string);
3858   __ and_(temp.reg(), Immediate(kStringRepresentationMask));
3859   __ cmpb(temp.reg(), Immediate(kConsStringTag));
3860   __ j(not_equal, &slow_case);
3861
3862   // ConsString.
3863   // Check that the right hand side is the empty string (ie if this is really a
3864   // flat string in a cons string).  If that is not the case we would rather go
3865   // to the runtime system now, to flatten the string.
3866   __ movq(temp.reg(), FieldOperand(object.reg(), ConsString::kSecondOffset));
3867   __ CompareRoot(temp.reg(), Heap::kEmptyStringRootIndex);
3868   __ j(not_equal, &slow_case);
3869   // Get the first of the two strings.
3870   __ movq(object.reg(), FieldOperand(object.reg(), ConsString::kFirstOffset));
3871   __ jmp(&try_again_with_new_string);
3872
3873   __ bind(&slow_case);
3874   // Move the undefined value into the result register, which will
3875   // trigger the slow case.
3876   __ LoadRoot(temp.reg(), Heap::kUndefinedValueRootIndex);
3877
3878   __ bind(&end);
3879   frame_->Push(&temp);
3880 }
3881
3882
3883 void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) {
3884   Comment(masm_, "[ GenerateCharFromCode");
3885   ASSERT(args->length() == 1);
3886
3887   Load(args->at(0));
3888   Result code = frame_->Pop();
3889   code.ToRegister();
3890   ASSERT(code.is_valid());
3891
3892   Result temp = allocator()->Allocate();
3893   ASSERT(temp.is_valid());
3894
3895   JumpTarget slow_case;
3896   JumpTarget exit;
3897
3898   // Fast case of Heap::LookupSingleCharacterStringFromCode.
3899   Condition is_smi = __ CheckSmi(code.reg());
3900   slow_case.Branch(NegateCondition(is_smi), &code, not_taken);
3901
3902   __ SmiToInteger32(kScratchRegister, code.reg());
3903   __ cmpl(kScratchRegister, Immediate(String::kMaxAsciiCharCode));
3904   slow_case.Branch(above, &code, not_taken);
3905
3906   __ Move(temp.reg(), Factory::single_character_string_cache());
3907   __ movq(temp.reg(), FieldOperand(temp.reg(),
3908                                    kScratchRegister, times_pointer_size,
3909                                    FixedArray::kHeaderSize));
3910   __ CompareRoot(temp.reg(), Heap::kUndefinedValueRootIndex);
3911   slow_case.Branch(equal, &code, not_taken);
3912   code.Unuse();
3913
3914   frame_->Push(&temp);
3915   exit.Jump();
3916
3917   slow_case.Bind(&code);
3918   frame_->Push(&code);
3919   Result result = frame_->CallRuntime(Runtime::kCharFromCode, 1);
3920   frame_->Push(&result);
3921
3922   exit.Bind();
3923 }
3924
3925
3926 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
3927   ASSERT(args->length() == 1);
3928   Load(args->at(0));
3929   Result value = frame_->Pop();
3930   value.ToRegister();
3931   ASSERT(value.is_valid());
3932   Condition positive_smi = masm_->CheckPositiveSmi(value.reg());
3933   value.Unuse();
3934   destination()->Split(positive_smi);
3935 }
3936
3937
3938 // Generates the Math.pow method - currently just calls runtime.
3939 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
3940   ASSERT(args->length() == 2);
3941   Load(args->at(0));
3942   Load(args->at(1));
3943   Result res = frame_->CallRuntime(Runtime::kMath_pow, 2);
3944   frame_->Push(&res);
3945 }
3946
3947
3948 // Generates the Math.sqrt method - currently just calls runtime.
3949 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
3950   ASSERT(args->length() == 1);
3951   Load(args->at(0));
3952   Result res = frame_->CallRuntime(Runtime::kMath_sqrt, 1);
3953   frame_->Push(&res);
3954 }
3955
3956
3957 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
3958   ASSERT(args->length() == 1);
3959   Load(args->at(0));
3960   Result value = frame_->Pop();
3961   value.ToRegister();
3962   ASSERT(value.is_valid());
3963   Condition is_smi = masm_->CheckSmi(value.reg());
3964   value.Unuse();
3965   destination()->Split(is_smi);
3966 }
3967
3968
3969 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
3970   // Conditionally generate a log call.
3971   // Args:
3972   //   0 (literal string): The type of logging (corresponds to the flags).
3973   //     This is used to determine whether or not to generate the log call.
3974   //   1 (string): Format string.  Access the string at argument index 2
3975   //     with '%2s' (see Logger::LogRuntime for all the formats).
3976   //   2 (array): Arguments to the format string.
3977   ASSERT_EQ(args->length(), 3);
3978 #ifdef ENABLE_LOGGING_AND_PROFILING
3979   if (ShouldGenerateLog(args->at(0))) {
3980     Load(args->at(1));
3981     Load(args->at(2));
3982     frame_->CallRuntime(Runtime::kLog, 2);
3983   }
3984 #endif
3985   // Finally, we're expected to leave a value on the top of the stack.
3986   frame_->Push(Factory::undefined_value());
3987 }
3988
3989
3990 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
3991   ASSERT(args->length() == 2);
3992
3993   // Load the two objects into registers and perform the comparison.
3994   Load(args->at(0));
3995   Load(args->at(1));
3996   Result right = frame_->Pop();
3997   Result left = frame_->Pop();
3998   right.ToRegister();
3999   left.ToRegister();
4000   __ cmpq(right.reg(), left.reg());
4001   right.Unuse();
4002   left.Unuse();
4003   destination()->Split(equal);
4004 }
4005
4006
4007 void CodeGenerator::GenerateGetFramePointer(ZoneList<Expression*>* args) {
4008   ASSERT(args->length() == 0);
4009   // RBP value is aligned, so it should be tagged as a smi (without necesarily
4010   // being padded as a smi, so it should not be treated as a smi.).
4011   ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
4012   Result rbp_as_smi = allocator_->Allocate();
4013   ASSERT(rbp_as_smi.is_valid());
4014   __ movq(rbp_as_smi.reg(), rbp);
4015   frame_->Push(&rbp_as_smi);
4016 }
4017
4018
4019 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
4020   ASSERT(args->length() == 0);
4021   frame_->SpillAll();
4022   __ push(rsi);
4023
4024   static const int num_arguments = 0;
4025   __ PrepareCallCFunction(num_arguments);
4026
4027   // Call V8::RandomPositiveSmi().
4028   __ CallCFunction(ExternalReference::random_positive_smi_function(),
4029                    num_arguments);
4030
4031   __ pop(rsi);
4032   Result result = allocator_->Allocate(rax);
4033   frame_->Push(&result);
4034 }
4035
4036
4037 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
4038   ASSERT_EQ(args->length(), 4);
4039
4040   // Load the arguments on the stack and call the runtime system.
4041   Load(args->at(0));
4042   Load(args->at(1));
4043   Load(args->at(2));
4044   Load(args->at(3));
4045   RegExpExecStub stub;
4046   Result result = frame_->CallStub(&stub, 4);
4047   frame_->Push(&result);
4048 }
4049
4050
4051 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
4052   ASSERT_EQ(args->length(), 1);
4053
4054   // Load the argument on the stack and jump to the runtime.
4055   Load(args->at(0));
4056
4057   NumberToStringStub stub;
4058   Result result = frame_->CallStub(&stub, 1);
4059   frame_->Push(&result);
4060 }
4061
4062
4063 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
4064   ASSERT_EQ(args->length(), 1);
4065   // Load the argument on the stack and jump to the runtime.
4066   Load(args->at(0));
4067   Result answer = frame_->CallRuntime(Runtime::kMath_sin, 1);
4068   frame_->Push(&answer);
4069 }
4070
4071
4072 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
4073   ASSERT_EQ(args->length(), 1);
4074   // Load the argument on the stack and jump to the runtime.
4075   Load(args->at(0));
4076   Result answer = frame_->CallRuntime(Runtime::kMath_cos, 1);
4077   frame_->Push(&answer);
4078 }
4079
4080
4081 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) {
4082   ASSERT_EQ(2, args->length());
4083
4084   Load(args->at(0));
4085   Load(args->at(1));
4086
4087   StringAddStub stub(NO_STRING_ADD_FLAGS);
4088   Result answer = frame_->CallStub(&stub, 2);
4089   frame_->Push(&answer);
4090 }
4091
4092
4093 void CodeGenerator::GenerateSubString(ZoneList<Expression*>* args) {
4094   ASSERT_EQ(3, args->length());
4095
4096   Load(args->at(0));
4097   Load(args->at(1));
4098   Load(args->at(2));
4099
4100   SubStringStub stub;
4101   Result answer = frame_->CallStub(&stub, 3);
4102   frame_->Push(&answer);
4103 }
4104
4105
4106 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
4107   ASSERT_EQ(2, args->length());
4108
4109   Load(args->at(0));
4110   Load(args->at(1));
4111
4112   StringCompareStub stub;
4113   Result answer = frame_->CallStub(&stub, 2);
4114   frame_->Push(&answer);
4115 }
4116
4117
4118 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
4119   ASSERT(args->length() == 1);
4120   JumpTarget leave, null, function, non_function_constructor;
4121   Load(args->at(0));  // Load the object.
4122   Result obj = frame_->Pop();
4123   obj.ToRegister();
4124   frame_->Spill(obj.reg());
4125
4126   // If the object is a smi, we return null.
4127   Condition is_smi = masm_->CheckSmi(obj.reg());
4128   null.Branch(is_smi);
4129
4130   // Check that the object is a JS object but take special care of JS
4131   // functions to make sure they have 'Function' as their class.
4132
4133   __ CmpObjectType(obj.reg(), FIRST_JS_OBJECT_TYPE, obj.reg());
4134   null.Branch(below);
4135
4136   // As long as JS_FUNCTION_TYPE is the last instance type and it is
4137   // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
4138   // LAST_JS_OBJECT_TYPE.
4139   ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
4140   ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
4141   __ CmpInstanceType(obj.reg(), JS_FUNCTION_TYPE);
4142   function.Branch(equal);
4143
4144   // Check if the constructor in the map is a function.
4145   __ movq(obj.reg(), FieldOperand(obj.reg(), Map::kConstructorOffset));
4146   __ CmpObjectType(obj.reg(), JS_FUNCTION_TYPE, kScratchRegister);
4147   non_function_constructor.Branch(not_equal);
4148
4149   // The obj register now contains the constructor function. Grab the
4150   // instance class name from there.
4151   __ movq(obj.reg(),
4152           FieldOperand(obj.reg(), JSFunction::kSharedFunctionInfoOffset));
4153   __ movq(obj.reg(),
4154           FieldOperand(obj.reg(),
4155                        SharedFunctionInfo::kInstanceClassNameOffset));
4156   frame_->Push(&obj);
4157   leave.Jump();
4158
4159   // Functions have class 'Function'.
4160   function.Bind();
4161   frame_->Push(Factory::function_class_symbol());
4162   leave.Jump();
4163
4164   // Objects with a non-function constructor have class 'Object'.
4165   non_function_constructor.Bind();
4166   frame_->Push(Factory::Object_symbol());
4167   leave.Jump();
4168
4169   // Non-JS objects have class null.
4170   null.Bind();
4171   frame_->Push(Factory::null_value());
4172
4173   // All done.
4174   leave.Bind();
4175 }
4176
4177
4178 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
4179   ASSERT(args->length() == 2);
4180   JumpTarget leave;
4181   Load(args->at(0));  // Load the object.
4182   Load(args->at(1));  // Load the value.
4183   Result value = frame_->Pop();
4184   Result object = frame_->Pop();
4185   value.ToRegister();
4186   object.ToRegister();
4187
4188   // if (object->IsSmi()) return value.
4189   Condition is_smi = masm_->CheckSmi(object.reg());
4190   leave.Branch(is_smi, &value);
4191
4192   // It is a heap object - get its map.
4193   Result scratch = allocator_->Allocate();
4194   ASSERT(scratch.is_valid());
4195   // if (!object->IsJSValue()) return value.
4196   __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg());
4197   leave.Branch(not_equal, &value);
4198
4199   // Store the value.
4200   __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg());
4201   // Update the write barrier.  Save the value as it will be
4202   // overwritten by the write barrier code and is needed afterward.
4203   Result duplicate_value = allocator_->Allocate();
4204   ASSERT(duplicate_value.is_valid());
4205   __ movq(duplicate_value.reg(), value.reg());
4206   // The object register is also overwritten by the write barrier and
4207   // possibly aliased in the frame.
4208   frame_->Spill(object.reg());
4209   __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(),
4210                  scratch.reg());
4211   object.Unuse();
4212   scratch.Unuse();
4213   duplicate_value.Unuse();
4214
4215   // Leave.
4216   leave.Bind(&value);
4217   frame_->Push(&value);
4218 }
4219
4220
4221 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
4222   ASSERT(args->length() == 1);
4223   JumpTarget leave;
4224   Load(args->at(0));  // Load the object.
4225   frame_->Dup();
4226   Result object = frame_->Pop();
4227   object.ToRegister();
4228   ASSERT(object.is_valid());
4229   // if (object->IsSmi()) return object.
4230   Condition is_smi = masm_->CheckSmi(object.reg());
4231   leave.Branch(is_smi);
4232   // It is a heap object - get map.
4233   Result temp = allocator()->Allocate();
4234   ASSERT(temp.is_valid());
4235   // if (!object->IsJSValue()) return object.
4236   __ CmpObjectType(object.reg(), JS_VALUE_TYPE, temp.reg());
4237   leave.Branch(not_equal);
4238   __ movq(temp.reg(), FieldOperand(object.reg(), JSValue::kValueOffset));
4239   object.Unuse();
4240   frame_->SetElementAt(0, &temp);
4241   leave.Bind();
4242 }
4243
4244
4245 // -----------------------------------------------------------------------------
4246 // CodeGenerator implementation of Expressions
4247
4248 void CodeGenerator::LoadAndSpill(Expression* expression) {
4249   // TODO(x64): No architecture specific code. Move to shared location.
4250   ASSERT(in_spilled_code());
4251   set_in_spilled_code(false);
4252   Load(expression);
4253   frame_->SpillAll();
4254   set_in_spilled_code(true);
4255 }
4256
4257
4258 void CodeGenerator::Load(Expression* expr) {
4259 #ifdef DEBUG
4260   int original_height = frame_->height();
4261 #endif
4262   ASSERT(!in_spilled_code());
4263   JumpTarget true_target;
4264   JumpTarget false_target;
4265   ControlDestination dest(&true_target, &false_target, true);
4266   LoadCondition(expr, &dest, false);
4267
4268   if (dest.false_was_fall_through()) {
4269     // The false target was just bound.
4270     JumpTarget loaded;
4271     frame_->Push(Factory::false_value());
4272     // There may be dangling jumps to the true target.
4273     if (true_target.is_linked()) {
4274       loaded.Jump();
4275       true_target.Bind();
4276       frame_->Push(Factory::true_value());
4277       loaded.Bind();
4278     }
4279
4280   } else if (dest.is_used()) {
4281     // There is true, and possibly false, control flow (with true as
4282     // the fall through).
4283     JumpTarget loaded;
4284     frame_->Push(Factory::true_value());
4285     if (false_target.is_linked()) {
4286       loaded.Jump();
4287       false_target.Bind();
4288       frame_->Push(Factory::false_value());
4289       loaded.Bind();
4290     }
4291
4292   } else {
4293     // We have a valid value on top of the frame, but we still may
4294     // have dangling jumps to the true and false targets from nested
4295     // subexpressions (eg, the left subexpressions of the
4296     // short-circuited boolean operators).
4297     ASSERT(has_valid_frame());
4298     if (true_target.is_linked() || false_target.is_linked()) {
4299       JumpTarget loaded;
4300       loaded.Jump();  // Don't lose the current TOS.
4301       if (true_target.is_linked()) {
4302         true_target.Bind();
4303         frame_->Push(Factory::true_value());
4304         if (false_target.is_linked()) {
4305           loaded.Jump();
4306         }
4307       }
4308       if (false_target.is_linked()) {
4309         false_target.Bind();
4310         frame_->Push(Factory::false_value());
4311       }
4312       loaded.Bind();
4313     }
4314   }
4315
4316   ASSERT(has_valid_frame());
4317   ASSERT(frame_->height() == original_height + 1);
4318 }
4319
4320
4321 // Emit code to load the value of an expression to the top of the
4322 // frame. If the expression is boolean-valued it may be compiled (or
4323 // partially compiled) into control flow to the control destination.
4324 // If force_control is true, control flow is forced.
4325 void CodeGenerator::LoadCondition(Expression* x,
4326                                   ControlDestination* dest,
4327                                   bool force_control) {
4328   ASSERT(!in_spilled_code());
4329   int original_height = frame_->height();
4330
4331   { CodeGenState new_state(this, dest);
4332     Visit(x);
4333
4334     // If we hit a stack overflow, we may not have actually visited
4335     // the expression.  In that case, we ensure that we have a
4336     // valid-looking frame state because we will continue to generate
4337     // code as we unwind the C++ stack.
4338     //
4339     // It's possible to have both a stack overflow and a valid frame
4340     // state (eg, a subexpression overflowed, visiting it returned
4341     // with a dummied frame state, and visiting this expression
4342     // returned with a normal-looking state).
4343     if (HasStackOverflow() &&
4344         !dest->is_used() &&
4345         frame_->height() == original_height) {
4346       dest->Goto(true);
4347     }
4348   }
4349
4350   if (force_control && !dest->is_used()) {
4351     // Convert the TOS value into flow to the control destination.
4352     // TODO(X64): Make control flow to control destinations work.
4353     ToBoolean(dest);
4354   }
4355
4356   ASSERT(!(force_control && !dest->is_used()));
4357   ASSERT(dest->is_used() || frame_->height() == original_height + 1);
4358 }
4359
4360
4361 // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and
4362 // convert it to a boolean in the condition code register or jump to
4363 // 'false_target'/'true_target' as appropriate.
4364 void CodeGenerator::ToBoolean(ControlDestination* dest) {
4365   Comment cmnt(masm_, "[ ToBoolean");
4366
4367   // The value to convert should be popped from the frame.
4368   Result value = frame_->Pop();
4369   value.ToRegister();
4370
4371   if (value.is_number()) {
4372     Comment cmnt(masm_, "ONLY_NUMBER");
4373     // Fast case if TypeInfo indicates only numbers.
4374     if (FLAG_debug_code) {
4375       __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number.");
4376     }
4377     // Smi => false iff zero.
4378     __ SmiCompare(value.reg(), Smi::FromInt(0));
4379     dest->false_target()->Branch(equal);
4380     Condition is_smi = masm_->CheckSmi(value.reg());
4381     dest->true_target()->Branch(is_smi);
4382     __ fldz();
4383     __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset));
4384     __ FCmp();
4385     value.Unuse();
4386     dest->Split(not_zero);
4387   } else {
4388     // Fast case checks.
4389     // 'false' => false.
4390     __ CompareRoot(value.reg(), Heap::kFalseValueRootIndex);
4391     dest->false_target()->Branch(equal);
4392
4393     // 'true' => true.
4394     __ CompareRoot(value.reg(), Heap::kTrueValueRootIndex);
4395     dest->true_target()->Branch(equal);
4396
4397     // 'undefined' => false.
4398     __ CompareRoot(value.reg(), Heap::kUndefinedValueRootIndex);
4399     dest->false_target()->Branch(equal);
4400
4401     // Smi => false iff zero.
4402     __ SmiCompare(value.reg(), Smi::FromInt(0));
4403     dest->false_target()->Branch(equal);
4404     Condition is_smi = masm_->CheckSmi(value.reg());
4405     dest->true_target()->Branch(is_smi);
4406
4407     // Call the stub for all other cases.
4408     frame_->Push(&value);  // Undo the Pop() from above.
4409     ToBooleanStub stub;
4410     Result temp = frame_->CallStub(&stub, 1);
4411     // Convert the result to a condition code.
4412     __ testq(temp.reg(), temp.reg());
4413     temp.Unuse();
4414     dest->Split(not_equal);
4415   }
4416 }
4417
4418
4419 void CodeGenerator::LoadUnsafeSmi(Register target, Handle<Object> value) {
4420   UNIMPLEMENTED();
4421   // TODO(X64): Implement security policy for loads of smis.
4422 }
4423
4424
4425 bool CodeGenerator::IsUnsafeSmi(Handle<Object> value) {
4426   return false;
4427 }
4428
4429 //------------------------------------------------------------------------------
4430 // CodeGenerator implementation of variables, lookups, and stores.
4431
4432 Reference::Reference(CodeGenerator* cgen,
4433                      Expression* expression,
4434                      bool  persist_after_get)
4435     : cgen_(cgen),
4436       expression_(expression),
4437       type_(ILLEGAL),
4438       persist_after_get_(persist_after_get) {
4439   cgen->LoadReference(this);
4440 }
4441
4442
4443 Reference::~Reference() {
4444   ASSERT(is_unloaded() || is_illegal());
4445 }
4446
4447
4448 void CodeGenerator::LoadReference(Reference* ref) {
4449   // References are loaded from both spilled and unspilled code.  Set the
4450   // state to unspilled to allow that (and explicitly spill after
4451   // construction at the construction sites).
4452   bool was_in_spilled_code = in_spilled_code_;
4453   in_spilled_code_ = false;
4454
4455   Comment cmnt(masm_, "[ LoadReference");
4456   Expression* e = ref->expression();
4457   Property* property = e->AsProperty();
4458   Variable* var = e->AsVariableProxy()->AsVariable();
4459
4460   if (property != NULL) {
4461     // The expression is either a property or a variable proxy that rewrites
4462     // to a property.
4463     Load(property->obj());
4464     if (property->key()->IsPropertyName()) {
4465       ref->set_type(Reference::NAMED);
4466     } else {
4467       Load(property->key());
4468       ref->set_type(Reference::KEYED);
4469     }
4470   } else if (var != NULL) {
4471     // The expression is a variable proxy that does not rewrite to a
4472     // property.  Global variables are treated as named property references.
4473     if (var->is_global()) {
4474       LoadGlobal();
4475       ref->set_type(Reference::NAMED);
4476     } else {
4477       ASSERT(var->slot() != NULL);
4478       ref->set_type(Reference::SLOT);
4479     }
4480   } else {
4481     // Anything else is a runtime error.
4482     Load(e);
4483     frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
4484   }
4485
4486   in_spilled_code_ = was_in_spilled_code;
4487 }
4488
4489
4490 void CodeGenerator::UnloadReference(Reference* ref) {
4491   // Pop a reference from the stack while preserving TOS.
4492   Comment cmnt(masm_, "[ UnloadReference");
4493   frame_->Nip(ref->size());
4494   ref->set_unloaded();
4495 }
4496
4497
4498 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
4499   // Currently, this assertion will fail if we try to assign to
4500   // a constant variable that is constant because it is read-only
4501   // (such as the variable referring to a named function expression).
4502   // We need to implement assignments to read-only variables.
4503   // Ideally, we should do this during AST generation (by converting
4504   // such assignments into expression statements); however, in general
4505   // we may not be able to make the decision until past AST generation,
4506   // that is when the entire program is known.
4507   ASSERT(slot != NULL);
4508   int index = slot->index();
4509   switch (slot->type()) {
4510     case Slot::PARAMETER:
4511       return frame_->ParameterAt(index);
4512
4513     case Slot::LOCAL:
4514       return frame_->LocalAt(index);
4515
4516     case Slot::CONTEXT: {
4517       // Follow the context chain if necessary.
4518       ASSERT(!tmp.is(rsi));  // do not overwrite context register
4519       Register context = rsi;
4520       int chain_length = scope()->ContextChainLength(slot->var()->scope());
4521       for (int i = 0; i < chain_length; i++) {
4522         // Load the closure.
4523         // (All contexts, even 'with' contexts, have a closure,
4524         // and it is the same for all contexts inside a function.
4525         // There is no need to go to the function context first.)
4526         __ movq(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
4527         // Load the function context (which is the incoming, outer context).
4528         __ movq(tmp, FieldOperand(tmp, JSFunction::kContextOffset));
4529         context = tmp;
4530       }
4531       // We may have a 'with' context now. Get the function context.
4532       // (In fact this mov may never be the needed, since the scope analysis
4533       // may not permit a direct context access in this case and thus we are
4534       // always at a function context. However it is safe to dereference be-
4535       // cause the function context of a function context is itself. Before
4536       // deleting this mov we should try to create a counter-example first,
4537       // though...)
4538       __ movq(tmp, ContextOperand(context, Context::FCONTEXT_INDEX));
4539       return ContextOperand(tmp, index);
4540     }
4541
4542     default:
4543       UNREACHABLE();
4544       return Operand(rsp, 0);
4545   }
4546 }
4547
4548
4549 Operand CodeGenerator::ContextSlotOperandCheckExtensions(Slot* slot,
4550                                                          Result tmp,
4551                                                          JumpTarget* slow) {
4552   ASSERT(slot->type() == Slot::CONTEXT);
4553   ASSERT(tmp.is_register());
4554   Register context = rsi;
4555
4556   for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) {
4557     if (s->num_heap_slots() > 0) {
4558       if (s->calls_eval()) {
4559         // Check that extension is NULL.
4560         __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX),
4561                 Immediate(0));
4562         slow->Branch(not_equal, not_taken);
4563       }
4564       __ movq(tmp.reg(), ContextOperand(context, Context::CLOSURE_INDEX));
4565       __ movq(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
4566       context = tmp.reg();
4567     }
4568   }
4569   // Check that last extension is NULL.
4570   __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0));
4571   slow->Branch(not_equal, not_taken);
4572   __ movq(tmp.reg(), ContextOperand(context, Context::FCONTEXT_INDEX));
4573   return ContextOperand(tmp.reg(), slot->index());
4574 }
4575
4576
4577 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
4578   if (slot->type() == Slot::LOOKUP) {
4579     ASSERT(slot->var()->is_dynamic());
4580
4581     JumpTarget slow;
4582     JumpTarget done;
4583     Result value;
4584
4585     // Generate fast-case code for variables that might be shadowed by
4586     // eval-introduced variables.  Eval is used a lot without
4587     // introducing variables.  In those cases, we do not want to
4588     // perform a runtime call for all variables in the scope
4589     // containing the eval.
4590     if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
4591       value = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow);
4592       // If there was no control flow to slow, we can exit early.
4593       if (!slow.is_linked()) {
4594         frame_->Push(&value);
4595         return;
4596       }
4597
4598       done.Jump(&value);
4599
4600     } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
4601       Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
4602       // Only generate the fast case for locals that rewrite to slots.
4603       // This rules out argument loads.
4604       if (potential_slot != NULL) {
4605         // Allocate a fresh register to use as a temp in
4606         // ContextSlotOperandCheckExtensions and to hold the result
4607         // value.
4608         value = allocator_->Allocate();
4609         ASSERT(value.is_valid());
4610         __ movq(value.reg(),
4611                ContextSlotOperandCheckExtensions(potential_slot,
4612                                                  value,
4613                                                  &slow));
4614         if (potential_slot->var()->mode() == Variable::CONST) {
4615           __ CompareRoot(value.reg(), Heap::kTheHoleValueRootIndex);
4616           done.Branch(not_equal, &value);
4617           __ LoadRoot(value.reg(), Heap::kUndefinedValueRootIndex);
4618         }
4619         // There is always control flow to slow from
4620         // ContextSlotOperandCheckExtensions so we have to jump around
4621         // it.
4622         done.Jump(&value);
4623       }
4624     }
4625
4626     slow.Bind();
4627     // A runtime call is inevitable.  We eagerly sync frame elements
4628     // to memory so that we can push the arguments directly into place
4629     // on top of the frame.
4630     frame_->SyncRange(0, frame_->element_count() - 1);
4631     frame_->EmitPush(rsi);
4632     __ movq(kScratchRegister, slot->var()->name(), RelocInfo::EMBEDDED_OBJECT);
4633     frame_->EmitPush(kScratchRegister);
4634     if (typeof_state == INSIDE_TYPEOF) {
4635        value =
4636          frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
4637     } else {
4638        value = frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
4639     }
4640
4641     done.Bind(&value);
4642     frame_->Push(&value);
4643
4644   } else if (slot->var()->mode() == Variable::CONST) {
4645     // Const slots may contain 'the hole' value (the constant hasn't been
4646     // initialized yet) which needs to be converted into the 'undefined'
4647     // value.
4648     //
4649     // We currently spill the virtual frame because constants use the
4650     // potentially unsafe direct-frame access of SlotOperand.
4651     VirtualFrame::SpilledScope spilled_scope;
4652     Comment cmnt(masm_, "[ Load const");
4653     JumpTarget exit;
4654     __ movq(rcx, SlotOperand(slot, rcx));
4655     __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex);
4656     exit.Branch(not_equal);
4657     __ LoadRoot(rcx, Heap::kUndefinedValueRootIndex);
4658     exit.Bind();
4659     frame_->EmitPush(rcx);
4660
4661   } else if (slot->type() == Slot::PARAMETER) {
4662     frame_->PushParameterAt(slot->index());
4663
4664   } else if (slot->type() == Slot::LOCAL) {
4665     frame_->PushLocalAt(slot->index());
4666
4667   } else {
4668     // The other remaining slot types (LOOKUP and GLOBAL) cannot reach
4669     // here.
4670     //
4671     // The use of SlotOperand below is safe for an unspilled frame
4672     // because it will always be a context slot.
4673     ASSERT(slot->type() == Slot::CONTEXT);
4674     Result temp = allocator_->Allocate();
4675     ASSERT(temp.is_valid());
4676     __ movq(temp.reg(), SlotOperand(slot, temp.reg()));
4677     frame_->Push(&temp);
4678   }
4679 }
4680
4681
4682 void CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot,
4683                                                   TypeofState state) {
4684   LoadFromSlot(slot, state);
4685
4686   // Bail out quickly if we're not using lazy arguments allocation.
4687   if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return;
4688
4689   // ... or if the slot isn't a non-parameter arguments slot.
4690   if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return;
4691
4692   // Pop the loaded value from the stack.
4693   Result value = frame_->Pop();
4694
4695   // If the loaded value is a constant, we know if the arguments
4696   // object has been lazily loaded yet.
4697   if (value.is_constant()) {
4698     if (value.handle()->IsTheHole()) {
4699       Result arguments = StoreArgumentsObject(false);
4700       frame_->Push(&arguments);
4701     } else {
4702       frame_->Push(&value);
4703     }
4704     return;
4705   }
4706
4707   // The loaded value is in a register. If it is the sentinel that
4708   // indicates that we haven't loaded the arguments object yet, we
4709   // need to do it now.
4710   JumpTarget exit;
4711   __ CompareRoot(value.reg(), Heap::kTheHoleValueRootIndex);
4712   frame_->Push(&value);
4713   exit.Branch(not_equal);
4714   Result arguments = StoreArgumentsObject(false);
4715   frame_->SetElementAt(0, &arguments);
4716   exit.Bind();
4717 }
4718
4719
4720 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
4721   if (slot->type() == Slot::LOOKUP) {
4722     ASSERT(slot->var()->is_dynamic());
4723
4724     // For now, just do a runtime call.  Since the call is inevitable,
4725     // we eagerly sync the virtual frame so we can directly push the
4726     // arguments into place.
4727     frame_->SyncRange(0, frame_->element_count() - 1);
4728
4729     frame_->EmitPush(rsi);
4730     frame_->EmitPush(slot->var()->name());
4731
4732     Result value;
4733     if (init_state == CONST_INIT) {
4734       // Same as the case for a normal store, but ignores attribute
4735       // (e.g. READ_ONLY) of context slot so that we can initialize const
4736       // properties (introduced via eval("const foo = (some expr);")). Also,
4737       // uses the current function context instead of the top context.
4738       //
4739       // Note that we must declare the foo upon entry of eval(), via a
4740       // context slot declaration, but we cannot initialize it at the same
4741       // time, because the const declaration may be at the end of the eval
4742       // code (sigh...) and the const variable may have been used before
4743       // (where its value is 'undefined'). Thus, we can only do the
4744       // initialization when we actually encounter the expression and when
4745       // the expression operands are defined and valid, and thus we need the
4746       // split into 2 operations: declaration of the context slot followed
4747       // by initialization.
4748       value = frame_->CallRuntime(Runtime::kInitializeConstContextSlot, 3);
4749     } else {
4750       value = frame_->CallRuntime(Runtime::kStoreContextSlot, 3);
4751     }
4752     // Storing a variable must keep the (new) value on the expression
4753     // stack. This is necessary for compiling chained assignment
4754     // expressions.
4755     frame_->Push(&value);
4756   } else {
4757     ASSERT(!slot->var()->is_dynamic());
4758
4759     JumpTarget exit;
4760     if (init_state == CONST_INIT) {
4761       ASSERT(slot->var()->mode() == Variable::CONST);
4762       // Only the first const initialization must be executed (the slot
4763       // still contains 'the hole' value). When the assignment is executed,
4764       // the code is identical to a normal store (see below).
4765       //
4766       // We spill the frame in the code below because the direct-frame
4767       // access of SlotOperand is potentially unsafe with an unspilled
4768       // frame.
4769       VirtualFrame::SpilledScope spilled_scope;
4770       Comment cmnt(masm_, "[ Init const");
4771       __ movq(rcx, SlotOperand(slot, rcx));
4772       __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex);
4773       exit.Branch(not_equal);
4774     }
4775
4776     // We must execute the store.  Storing a variable must keep the (new)
4777     // value on the stack. This is necessary for compiling assignment
4778     // expressions.
4779     //
4780     // Note: We will reach here even with slot->var()->mode() ==
4781     // Variable::CONST because of const declarations which will initialize
4782     // consts to 'the hole' value and by doing so, end up calling this code.
4783     if (slot->type() == Slot::PARAMETER) {
4784       frame_->StoreToParameterAt(slot->index());
4785     } else if (slot->type() == Slot::LOCAL) {
4786       frame_->StoreToLocalAt(slot->index());
4787     } else {
4788       // The other slot types (LOOKUP and GLOBAL) cannot reach here.
4789       //
4790       // The use of SlotOperand below is safe for an unspilled frame
4791       // because the slot is a context slot.
4792       ASSERT(slot->type() == Slot::CONTEXT);
4793       frame_->Dup();
4794       Result value = frame_->Pop();
4795       value.ToRegister();
4796       Result start = allocator_->Allocate();
4797       ASSERT(start.is_valid());
4798       __ movq(SlotOperand(slot, start.reg()), value.reg());
4799       // RecordWrite may destroy the value registers.
4800       //
4801       // TODO(204): Avoid actually spilling when the value is not
4802       // needed (probably the common case).
4803       frame_->Spill(value.reg());
4804       int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
4805       Result temp = allocator_->Allocate();
4806       ASSERT(temp.is_valid());
4807       __ RecordWrite(start.reg(), offset, value.reg(), temp.reg());
4808       // The results start, value, and temp are unused by going out of
4809       // scope.
4810     }
4811
4812     exit.Bind();
4813   }
4814 }
4815
4816
4817 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions(
4818     Slot* slot,
4819     TypeofState typeof_state,
4820     JumpTarget* slow) {
4821   // Check that no extension objects have been created by calls to
4822   // eval from the current scope to the global scope.
4823   Register context = rsi;
4824   Result tmp = allocator_->Allocate();
4825   ASSERT(tmp.is_valid());  // All non-reserved registers were available.
4826
4827   Scope* s = scope();
4828   while (s != NULL) {
4829     if (s->num_heap_slots() > 0) {
4830       if (s->calls_eval()) {
4831         // Check that extension is NULL.
4832         __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX),
4833                Immediate(0));
4834         slow->Branch(not_equal, not_taken);
4835       }
4836       // Load next context in chain.
4837       __ movq(tmp.reg(), ContextOperand(context, Context::CLOSURE_INDEX));
4838       __ movq(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
4839       context = tmp.reg();
4840     }
4841     // If no outer scope calls eval, we do not need to check more
4842     // context extensions.  If we have reached an eval scope, we check
4843     // all extensions from this point.
4844     if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
4845     s = s->outer_scope();
4846   }
4847
4848   if (s->is_eval_scope()) {
4849     // Loop up the context chain.  There is no frame effect so it is
4850     // safe to use raw labels here.
4851     Label next, fast;
4852     if (!context.is(tmp.reg())) {
4853       __ movq(tmp.reg(), context);
4854     }
4855     // Load map for comparison into register, outside loop.
4856     __ LoadRoot(kScratchRegister, Heap::kGlobalContextMapRootIndex);
4857     __ bind(&next);
4858     // Terminate at global context.
4859     __ cmpq(kScratchRegister, FieldOperand(tmp.reg(), HeapObject::kMapOffset));
4860     __ j(equal, &fast);
4861     // Check that extension is NULL.
4862     __ cmpq(ContextOperand(tmp.reg(), Context::EXTENSION_INDEX), Immediate(0));
4863     slow->Branch(not_equal);
4864     // Load next context in chain.
4865     __ movq(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX));
4866     __ movq(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
4867     __ jmp(&next);
4868     __ bind(&fast);
4869   }
4870   tmp.Unuse();
4871
4872   // All extension objects were empty and it is safe to use a global
4873   // load IC call.
4874   LoadGlobal();
4875   frame_->Push(slot->var()->name());
4876   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
4877                          ? RelocInfo::CODE_TARGET
4878                          : RelocInfo::CODE_TARGET_CONTEXT;
4879   Result answer = frame_->CallLoadIC(mode);
4880   // A test rax instruction following the call signals that the inobject
4881   // property case was inlined.  Ensure that there is not a test rax
4882   // instruction here.
4883   masm_->nop();
4884   // Discard the global object. The result is in answer.
4885   frame_->Drop();
4886   return answer;
4887 }
4888
4889
4890 void CodeGenerator::LoadGlobal() {
4891   if (in_spilled_code()) {
4892     frame_->EmitPush(GlobalObject());
4893   } else {
4894     Result temp = allocator_->Allocate();
4895     __ movq(temp.reg(), GlobalObject());
4896     frame_->Push(&temp);
4897   }
4898 }
4899
4900
4901 void CodeGenerator::LoadGlobalReceiver() {
4902   Result temp = allocator_->Allocate();
4903   Register reg = temp.reg();
4904   __ movq(reg, GlobalObject());
4905   __ movq(reg, FieldOperand(reg, GlobalObject::kGlobalReceiverOffset));
4906   frame_->Push(&temp);
4907 }
4908
4909
4910 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() {
4911   if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION;
4912   ASSERT(scope()->arguments_shadow() != NULL);
4913   // We don't want to do lazy arguments allocation for functions that
4914   // have heap-allocated contexts, because it interfers with the
4915   // uninitialized const tracking in the context objects.
4916   return (scope()->num_heap_slots() > 0)
4917       ? EAGER_ARGUMENTS_ALLOCATION
4918       : LAZY_ARGUMENTS_ALLOCATION;
4919 }
4920
4921
4922 Result CodeGenerator::StoreArgumentsObject(bool initial) {
4923   ArgumentsAllocationMode mode = ArgumentsMode();
4924   ASSERT(mode != NO_ARGUMENTS_ALLOCATION);
4925
4926   Comment cmnt(masm_, "[ store arguments object");
4927   if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) {
4928     // When using lazy arguments allocation, we store the hole value
4929     // as a sentinel indicating that the arguments object hasn't been
4930     // allocated yet.
4931     frame_->Push(Factory::the_hole_value());
4932   } else {
4933     ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
4934     frame_->PushFunction();
4935     frame_->PushReceiverSlotAddress();
4936     frame_->Push(Smi::FromInt(scope()->num_parameters()));
4937     Result result = frame_->CallStub(&stub, 3);
4938     frame_->Push(&result);
4939   }
4940
4941
4942   Variable* arguments = scope()->arguments()->var();
4943   Variable* shadow = scope()->arguments_shadow()->var();
4944   ASSERT(arguments != NULL && arguments->slot() != NULL);
4945   ASSERT(shadow != NULL && shadow->slot() != NULL);
4946   JumpTarget done;
4947   bool skip_arguments = false;
4948   if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) {
4949     // We have to skip storing into the arguments slot if it has
4950     // already been written to. This can happen if the a function
4951     // has a local variable named 'arguments'.
4952     LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF);
4953     Result probe = frame_->Pop();
4954     if (probe.is_constant()) {
4955       // We have to skip updating the arguments object if it has been
4956       // assigned a proper value.
4957       skip_arguments = !probe.handle()->IsTheHole();
4958     } else {
4959       __ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex);
4960       probe.Unuse();
4961       done.Branch(not_equal);
4962     }
4963   }
4964   if (!skip_arguments) {
4965     StoreToSlot(arguments->slot(), NOT_CONST_INIT);
4966     if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind();
4967   }
4968   StoreToSlot(shadow->slot(), NOT_CONST_INIT);
4969   return frame_->Pop();
4970 }
4971
4972
4973 void CodeGenerator::LoadTypeofExpression(Expression* expr) {
4974   // Special handling of identifiers as subexpressions of typeof.
4975   Variable* variable = expr->AsVariableProxy()->AsVariable();
4976   if (variable != NULL && !variable->is_this() && variable->is_global()) {
4977     // For a global variable we build the property reference
4978     // <global>.<variable> and perform a (regular non-contextual) property
4979     // load to make sure we do not get reference errors.
4980     Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX);
4981     Literal key(variable->name());
4982     Property property(&global, &key, RelocInfo::kNoPosition);
4983     Reference ref(this, &property);
4984     ref.GetValue();
4985   } else if (variable != NULL && variable->slot() != NULL) {
4986     // For a variable that rewrites to a slot, we signal it is the immediate
4987     // subexpression of a typeof.
4988     LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF);
4989   } else {
4990     // Anything else can be handled normally.
4991     Load(expr);
4992   }
4993 }
4994
4995
4996 void CodeGenerator::Comparison(AstNode* node,
4997                                Condition cc,
4998                                bool strict,
4999                                ControlDestination* dest) {
5000   // Strict only makes sense for equality comparisons.
5001   ASSERT(!strict || cc == equal);
5002
5003   Result left_side;
5004   Result right_side;
5005   // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
5006   if (cc == greater || cc == less_equal) {
5007     cc = ReverseCondition(cc);
5008     left_side = frame_->Pop();
5009     right_side = frame_->Pop();
5010   } else {
5011     right_side = frame_->Pop();
5012     left_side = frame_->Pop();
5013   }
5014   ASSERT(cc == less || cc == equal || cc == greater_equal);
5015
5016   // If either side is a constant smi, optimize the comparison.
5017   bool left_side_constant_smi =
5018       left_side.is_constant() && left_side.handle()->IsSmi();
5019   bool right_side_constant_smi =
5020       right_side.is_constant() && right_side.handle()->IsSmi();
5021   bool left_side_constant_null =
5022       left_side.is_constant() && left_side.handle()->IsNull();
5023   bool right_side_constant_null =
5024       right_side.is_constant() && right_side.handle()->IsNull();
5025
5026   if (left_side_constant_smi || right_side_constant_smi) {
5027     if (left_side_constant_smi && right_side_constant_smi) {
5028       // Trivial case, comparing two constants.
5029       int left_value = Smi::cast(*left_side.handle())->value();
5030       int right_value = Smi::cast(*right_side.handle())->value();
5031       switch (cc) {
5032         case less:
5033           dest->Goto(left_value < right_value);
5034           break;
5035         case equal:
5036           dest->Goto(left_value == right_value);
5037           break;
5038         case greater_equal:
5039           dest->Goto(left_value >= right_value);
5040           break;
5041         default:
5042           UNREACHABLE();
5043       }
5044     } else {
5045       // Only one side is a constant Smi.
5046       // If left side is a constant Smi, reverse the operands.
5047       // Since one side is a constant Smi, conversion order does not matter.
5048       if (left_side_constant_smi) {
5049         Result temp = left_side;
5050         left_side = right_side;
5051         right_side = temp;
5052         cc = ReverseCondition(cc);
5053         // This may reintroduce greater or less_equal as the value of cc.
5054         // CompareStub and the inline code both support all values of cc.
5055       }
5056       // Implement comparison against a constant Smi, inlining the case
5057       // where both sides are Smis.
5058       left_side.ToRegister();
5059       Register left_reg = left_side.reg();
5060       Handle<Object> right_val = right_side.handle();
5061
5062       // Here we split control flow to the stub call and inlined cases
5063       // before finally splitting it to the control destination.  We use
5064       // a jump target and branching to duplicate the virtual frame at
5065       // the first split.  We manually handle the off-frame references
5066       // by reconstituting them on the non-fall-through path.
5067       JumpTarget is_smi;
5068
5069       Condition left_is_smi = masm_->CheckSmi(left_side.reg());
5070       is_smi.Branch(left_is_smi);
5071
5072       bool is_loop_condition = (node->AsExpression() != NULL) &&
5073           node->AsExpression()->is_loop_condition();
5074       if (!is_loop_condition && right_val->IsSmi()) {
5075         // Right side is a constant smi and left side has been checked
5076         // not to be a smi.
5077         JumpTarget not_number;
5078         __ Cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
5079                Factory::heap_number_map());
5080         not_number.Branch(not_equal, &left_side);
5081         __ movsd(xmm1,
5082                  FieldOperand(left_reg, HeapNumber::kValueOffset));
5083         int value = Smi::cast(*right_val)->value();
5084         if (value == 0) {
5085           __ xorpd(xmm0, xmm0);
5086         } else {
5087           Result temp = allocator()->Allocate();
5088           __ movl(temp.reg(), Immediate(value));
5089           __ cvtlsi2sd(xmm0, temp.reg());
5090           temp.Unuse();
5091         }
5092         __ ucomisd(xmm1, xmm0);
5093         // Jump to builtin for NaN.
5094         not_number.Branch(parity_even, &left_side);
5095         left_side.Unuse();
5096         Condition double_cc = cc;
5097         switch (cc) {
5098           case less:          double_cc = below;       break;
5099           case equal:         double_cc = equal;       break;
5100           case less_equal:    double_cc = below_equal; break;
5101           case greater:       double_cc = above;       break;
5102           case greater_equal: double_cc = above_equal; break;
5103           default: UNREACHABLE();
5104         }
5105         dest->true_target()->Branch(double_cc);
5106         dest->false_target()->Jump();
5107         not_number.Bind(&left_side);
5108       }
5109
5110       // Setup and call the compare stub.
5111       CompareStub stub(cc, strict);
5112       Result result = frame_->CallStub(&stub, &left_side, &right_side);
5113       result.ToRegister();
5114       __ testq(result.reg(), result.reg());
5115       result.Unuse();
5116       dest->true_target()->Branch(cc);
5117       dest->false_target()->Jump();
5118
5119       is_smi.Bind();
5120       left_side = Result(left_reg);
5121       right_side = Result(right_val);
5122       // Test smi equality and comparison by signed int comparison.
5123       // Both sides are smis, so we can use an Immediate.
5124       __ SmiCompare(left_side.reg(), Smi::cast(*right_side.handle()));
5125       left_side.Unuse();
5126       right_side.Unuse();
5127       dest->Split(cc);
5128     }
5129   } else if (cc == equal &&
5130              (left_side_constant_null || right_side_constant_null)) {
5131     // To make null checks efficient, we check if either the left side or
5132     // the right side is the constant 'null'.
5133     // If so, we optimize the code by inlining a null check instead of
5134     // calling the (very) general runtime routine for checking equality.
5135     Result operand = left_side_constant_null ? right_side : left_side;
5136     right_side.Unuse();
5137     left_side.Unuse();
5138     operand.ToRegister();
5139     __ CompareRoot(operand.reg(), Heap::kNullValueRootIndex);
5140     if (strict) {
5141       operand.Unuse();
5142       dest->Split(equal);
5143     } else {
5144       // The 'null' value is only equal to 'undefined' if using non-strict
5145       // comparisons.
5146       dest->true_target()->Branch(equal);
5147       __ CompareRoot(operand.reg(), Heap::kUndefinedValueRootIndex);
5148       dest->true_target()->Branch(equal);
5149       Condition is_smi = masm_->CheckSmi(operand.reg());
5150       dest->false_target()->Branch(is_smi);
5151
5152       // It can be an undetectable object.
5153       // Use a scratch register in preference to spilling operand.reg().
5154       Result temp = allocator()->Allocate();
5155       ASSERT(temp.is_valid());
5156       __ movq(temp.reg(),
5157               FieldOperand(operand.reg(), HeapObject::kMapOffset));
5158       __ testb(FieldOperand(temp.reg(), Map::kBitFieldOffset),
5159                Immediate(1 << Map::kIsUndetectable));
5160       temp.Unuse();
5161       operand.Unuse();
5162       dest->Split(not_zero);
5163     }
5164   } else {  // Neither side is a constant Smi or null.
5165     // If either side is a non-smi constant, skip the smi check.
5166     bool known_non_smi =
5167         (left_side.is_constant() && !left_side.handle()->IsSmi()) ||
5168         (right_side.is_constant() && !right_side.handle()->IsSmi());
5169     left_side.ToRegister();
5170     right_side.ToRegister();
5171
5172     if (known_non_smi) {
5173       // When non-smi, call out to the compare stub.
5174       CompareStub stub(cc, strict);
5175       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
5176       // The result is a Smi, which is negative, zero, or positive.
5177       __ SmiTest(answer.reg());  // Sets both zero and sign flag.
5178       answer.Unuse();
5179       dest->Split(cc);
5180     } else {
5181       // Here we split control flow to the stub call and inlined cases
5182       // before finally splitting it to the control destination.  We use
5183       // a jump target and branching to duplicate the virtual frame at
5184       // the first split.  We manually handle the off-frame references
5185       // by reconstituting them on the non-fall-through path.
5186       JumpTarget is_smi;
5187       Register left_reg = left_side.reg();
5188       Register right_reg = right_side.reg();
5189
5190       Condition both_smi = masm_->CheckBothSmi(left_reg, right_reg);
5191       is_smi.Branch(both_smi);
5192       // When non-smi, call out to the compare stub.
5193       CompareStub stub(cc, strict);
5194       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
5195       __ SmiTest(answer.reg());  // Sets both zero and sign flags.
5196       answer.Unuse();
5197       dest->true_target()->Branch(cc);
5198       dest->false_target()->Jump();
5199
5200       is_smi.Bind();
5201       left_side = Result(left_reg);
5202       right_side = Result(right_reg);
5203       __ SmiCompare(left_side.reg(), right_side.reg());
5204       right_side.Unuse();
5205       left_side.Unuse();
5206       dest->Split(cc);
5207     }
5208   }
5209 }
5210
5211
5212 class DeferredInlineBinaryOperation: public DeferredCode {
5213  public:
5214   DeferredInlineBinaryOperation(Token::Value op,
5215                                 Register dst,
5216                                 Register left,
5217                                 Register right,
5218                                 OverwriteMode mode)
5219       : op_(op), dst_(dst), left_(left), right_(right), mode_(mode) {
5220     set_comment("[ DeferredInlineBinaryOperation");
5221   }
5222
5223   virtual void Generate();
5224
5225  private:
5226   Token::Value op_;
5227   Register dst_;
5228   Register left_;
5229   Register right_;
5230   OverwriteMode mode_;
5231 };
5232
5233
5234 void DeferredInlineBinaryOperation::Generate() {
5235   GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB);
5236   stub.GenerateCall(masm_, left_, right_);
5237   if (!dst_.is(rax)) __ movq(dst_, rax);
5238 }
5239
5240
5241 void CodeGenerator::GenericBinaryOperation(Token::Value op,
5242                                            StaticType* type,
5243                                            OverwriteMode overwrite_mode) {
5244   Comment cmnt(masm_, "[ BinaryOperation");
5245   Comment cmnt_token(masm_, Token::String(op));
5246
5247   if (op == Token::COMMA) {
5248     // Simply discard left value.
5249     frame_->Nip(1);
5250     return;
5251   }
5252
5253   Result right = frame_->Pop();
5254   Result left = frame_->Pop();
5255
5256   if (op == Token::ADD) {
5257     bool left_is_string = left.is_constant() && left.handle()->IsString();
5258     bool right_is_string = right.is_constant() && right.handle()->IsString();
5259     if (left_is_string || right_is_string) {
5260       frame_->Push(&left);
5261       frame_->Push(&right);
5262       Result answer;
5263       if (left_is_string) {
5264         if (right_is_string) {
5265           // TODO(lrn): if both are constant strings
5266           // -- do a compile time cons, if allocation during codegen is allowed.
5267           answer = frame_->CallRuntime(Runtime::kStringAdd, 2);
5268         } else {
5269           answer =
5270             frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2);
5271         }
5272       } else if (right_is_string) {
5273         answer =
5274           frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
5275       }
5276       frame_->Push(&answer);
5277       return;
5278     }
5279     // Neither operand is known to be a string.
5280   }
5281
5282   bool left_is_smi_constant = left.is_constant() && left.handle()->IsSmi();
5283   bool left_is_non_smi_constant = left.is_constant() && !left.handle()->IsSmi();
5284   bool right_is_smi_constant = right.is_constant() && right.handle()->IsSmi();
5285   bool right_is_non_smi_constant =
5286       right.is_constant() && !right.handle()->IsSmi();
5287
5288   if (left_is_smi_constant && right_is_smi_constant) {
5289     // Compute the constant result at compile time, and leave it on the frame.
5290     int left_int = Smi::cast(*left.handle())->value();
5291     int right_int = Smi::cast(*right.handle())->value();
5292     if (FoldConstantSmis(op, left_int, right_int)) return;
5293   }
5294
5295   // Get number type of left and right sub-expressions.
5296   TypeInfo operands_type =
5297       TypeInfo::Combine(left.type_info(), right.type_info());
5298
5299   Result answer;
5300   if (left_is_non_smi_constant || right_is_non_smi_constant) {
5301     GenericBinaryOpStub stub(op,
5302                              overwrite_mode,
5303                              NO_SMI_CODE_IN_STUB,
5304                              operands_type);
5305     answer = stub.GenerateCall(masm_, frame_, &left, &right);
5306   } else if (right_is_smi_constant) {
5307     answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
5308                                         type, false, overwrite_mode);
5309   } else if (left_is_smi_constant) {
5310     answer = ConstantSmiBinaryOperation(op, &right, left.handle(),
5311                                         type, true, overwrite_mode);
5312   } else {
5313     // Set the flags based on the operation, type and loop nesting level.
5314     // Bit operations always assume they likely operate on Smis. Still only
5315     // generate the inline Smi check code if this operation is part of a loop.
5316     // For all other operations only inline the Smi check code for likely smis
5317     // if the operation is part of a loop.
5318     if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) {
5319       answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
5320     } else {
5321       GenericBinaryOpStub stub(op,
5322                                overwrite_mode,
5323                                NO_GENERIC_BINARY_FLAGS,
5324                                operands_type);
5325       answer = stub.GenerateCall(masm_, frame_, &left, &right);
5326     }
5327   }
5328
5329   // Set TypeInfo of result according to the operation performed.
5330   // We rely on the fact that smis have a 32 bit payload on x64.
5331   ASSERT(kSmiValueSize == 32);
5332   TypeInfo result_type = TypeInfo::Unknown();
5333   switch (op) {
5334     case Token::COMMA:
5335       result_type = right.type_info();
5336       break;
5337     case Token::OR:
5338     case Token::AND:
5339       // Result type can be either of the two input types.
5340       result_type = operands_type;
5341       break;
5342     case Token::BIT_OR:
5343     case Token::BIT_XOR:
5344     case Token::BIT_AND:
5345       // Result is always a smi.
5346       result_type = TypeInfo::Smi();
5347       break;
5348     case Token::SAR:
5349     case Token::SHL:
5350       // Result is always a smi.
5351       result_type = TypeInfo::Smi();
5352       break;
5353     case Token::SHR:
5354       // Result of x >>> y is always a smi if y >= 1, otherwise a number.
5355       result_type = (right.is_constant() && right.handle()->IsSmi()
5356                      && Smi::cast(*right.handle())->value() >= 1)
5357           ? TypeInfo::Smi()
5358           : TypeInfo::Number();
5359       break;
5360     case Token::ADD:
5361       // Result could be a string or a number. Check types of inputs.
5362       result_type = operands_type.IsNumber()
5363           ? TypeInfo::Number()
5364           : TypeInfo::Unknown();
5365       break;
5366     case Token::SUB:
5367     case Token::MUL:
5368     case Token::DIV:
5369     case Token::MOD:
5370       // Result is always a number.
5371       result_type = TypeInfo::Number();
5372       break;
5373     default:
5374       UNREACHABLE();
5375   }
5376   answer.set_type_info(result_type);
5377   frame_->Push(&answer);
5378 }
5379
5380
5381 // Emit a LoadIC call to get the value from receiver and leave it in
5382 // dst.  The receiver register is restored after the call.
5383 class DeferredReferenceGetNamedValue: public DeferredCode {
5384  public:
5385   DeferredReferenceGetNamedValue(Register dst,
5386                                  Register receiver,
5387                                  Handle<String> name)
5388       : dst_(dst), receiver_(receiver),  name_(name) {
5389     set_comment("[ DeferredReferenceGetNamedValue");
5390   }
5391
5392   virtual void Generate();
5393
5394   Label* patch_site() { return &patch_site_; }
5395
5396  private:
5397   Label patch_site_;
5398   Register dst_;
5399   Register receiver_;
5400   Handle<String> name_;
5401 };
5402
5403
5404 void DeferredReferenceGetNamedValue::Generate() {
5405   __ push(receiver_);
5406   __ Move(rcx, name_);
5407   Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
5408   __ Call(ic, RelocInfo::CODE_TARGET);
5409   // The call must be followed by a test rax instruction to indicate
5410   // that the inobject property case was inlined.
5411   //
5412   // Store the delta to the map check instruction here in the test
5413   // instruction.  Use masm_-> instead of the __ macro since the
5414   // latter can't return a value.
5415   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
5416   // Here we use masm_-> instead of the __ macro because this is the
5417   // instruction that gets patched and coverage code gets in the way.
5418   masm_->testl(rax, Immediate(-delta_to_patch_site));
5419   __ IncrementCounter(&Counters::named_load_inline_miss, 1);
5420
5421   if (!dst_.is(rax)) __ movq(dst_, rax);
5422   __ pop(receiver_);
5423 }
5424
5425
5426 void DeferredInlineSmiAdd::Generate() {
5427   GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, NO_SMI_CODE_IN_STUB);
5428   igostub.GenerateCall(masm_, dst_, value_);
5429   if (!dst_.is(rax)) __ movq(dst_, rax);
5430 }
5431
5432
5433 void DeferredInlineSmiAddReversed::Generate() {
5434   GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, NO_SMI_CODE_IN_STUB);
5435   igostub.GenerateCall(masm_, value_, dst_);
5436   if (!dst_.is(rax)) __ movq(dst_, rax);
5437 }
5438
5439
5440 void DeferredInlineSmiSub::Generate() {
5441   GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, NO_SMI_CODE_IN_STUB);
5442   igostub.GenerateCall(masm_, dst_, value_);
5443   if (!dst_.is(rax)) __ movq(dst_, rax);
5444 }
5445
5446
5447 void DeferredInlineSmiOperation::Generate() {
5448   // For mod we don't generate all the Smi code inline.
5449   GenericBinaryOpStub stub(
5450       op_,
5451       overwrite_mode_,
5452       (op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB);
5453   stub.GenerateCall(masm_, src_, value_);
5454   if (!dst_.is(rax)) __ movq(dst_, rax);
5455 }
5456
5457
5458 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
5459                                                  Result* operand,
5460                                                  Handle<Object> value,
5461                                                  StaticType* type,
5462                                                  bool reversed,
5463                                                  OverwriteMode overwrite_mode) {
5464   // NOTE: This is an attempt to inline (a bit) more of the code for
5465   // some possible smi operations (like + and -) when (at least) one
5466   // of the operands is a constant smi.
5467   // Consumes the argument "operand".
5468
5469   // TODO(199): Optimize some special cases of operations involving a
5470   // smi literal (multiply by 2, shift by 0, etc.).
5471   if (IsUnsafeSmi(value)) {
5472     Result unsafe_operand(value);
5473     if (reversed) {
5474       return LikelySmiBinaryOperation(op, &unsafe_operand, operand,
5475                                overwrite_mode);
5476     } else {
5477       return LikelySmiBinaryOperation(op, operand, &unsafe_operand,
5478                                overwrite_mode);
5479     }
5480   }
5481
5482   // Get the literal value.
5483   Smi* smi_value = Smi::cast(*value);
5484   int int_value = smi_value->value();
5485
5486   Result answer;
5487   switch (op) {
5488     case Token::ADD: {
5489       operand->ToRegister();
5490       frame_->Spill(operand->reg());
5491       DeferredCode* deferred = NULL;
5492       if (reversed) {
5493         deferred = new DeferredInlineSmiAddReversed(operand->reg(),
5494                                                     smi_value,
5495                                                     overwrite_mode);
5496       } else {
5497         deferred = new DeferredInlineSmiAdd(operand->reg(),
5498                                             smi_value,
5499                                             overwrite_mode);
5500       }
5501       __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5502       __ SmiAddConstant(operand->reg(),
5503                         operand->reg(),
5504                         smi_value,
5505                         deferred->entry_label());
5506       deferred->BindExit();
5507       answer = *operand;
5508       break;
5509     }
5510
5511     case Token::SUB: {
5512       if (reversed) {
5513         Result constant_operand(value);
5514         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
5515                                           overwrite_mode);
5516       } else {
5517         operand->ToRegister();
5518         frame_->Spill(operand->reg());
5519         DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(),
5520                                                           smi_value,
5521                                                           overwrite_mode);
5522         __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5523         // A smi currently fits in a 32-bit Immediate.
5524         __ SmiSubConstant(operand->reg(),
5525                           operand->reg(),
5526                           smi_value,
5527                           deferred->entry_label());
5528         deferred->BindExit();
5529         answer = *operand;
5530       }
5531       break;
5532     }
5533
5534     case Token::SAR:
5535       if (reversed) {
5536         Result constant_operand(value);
5537         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
5538                                           overwrite_mode);
5539       } else {
5540         // Only the least significant 5 bits of the shift value are used.
5541         // In the slow case, this masking is done inside the runtime call.
5542         int shift_value = int_value & 0x1f;
5543         operand->ToRegister();
5544         frame_->Spill(operand->reg());
5545         DeferredInlineSmiOperation* deferred =
5546             new DeferredInlineSmiOperation(op,
5547                                            operand->reg(),
5548                                            operand->reg(),
5549                                            smi_value,
5550                                            overwrite_mode);
5551         __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5552         __ SmiShiftArithmeticRightConstant(operand->reg(),
5553                                            operand->reg(),
5554                                            shift_value);
5555         deferred->BindExit();
5556         answer = *operand;
5557       }
5558       break;
5559
5560     case Token::SHR:
5561       if (reversed) {
5562         Result constant_operand(value);
5563         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
5564                                           overwrite_mode);
5565       } else {
5566         // Only the least significant 5 bits of the shift value are used.
5567         // In the slow case, this masking is done inside the runtime call.
5568         int shift_value = int_value & 0x1f;
5569         operand->ToRegister();
5570         answer = allocator()->Allocate();
5571         ASSERT(answer.is_valid());
5572         DeferredInlineSmiOperation* deferred =
5573             new DeferredInlineSmiOperation(op,
5574                                            answer.reg(),
5575                                            operand->reg(),
5576                                            smi_value,
5577                                            overwrite_mode);
5578         __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5579         __ SmiShiftLogicalRightConstant(answer.reg(),
5580                                         operand->reg(),
5581                                         shift_value,
5582                                         deferred->entry_label());
5583         deferred->BindExit();
5584         operand->Unuse();
5585       }
5586       break;
5587
5588     case Token::SHL:
5589       if (reversed) {
5590         Result constant_operand(value);
5591         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
5592                                           overwrite_mode);
5593       } else {
5594         // Only the least significant 5 bits of the shift value are used.
5595         // In the slow case, this masking is done inside the runtime call.
5596         int shift_value = int_value & 0x1f;
5597         operand->ToRegister();
5598         if (shift_value == 0) {
5599           // Spill operand so it can be overwritten in the slow case.
5600           frame_->Spill(operand->reg());
5601           DeferredInlineSmiOperation* deferred =
5602               new DeferredInlineSmiOperation(op,
5603                                              operand->reg(),
5604                                              operand->reg(),
5605                                              smi_value,
5606                                              overwrite_mode);
5607           __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5608           deferred->BindExit();
5609           answer = *operand;
5610         } else {
5611           // Use a fresh temporary for nonzero shift values.
5612           answer = allocator()->Allocate();
5613           ASSERT(answer.is_valid());
5614           DeferredInlineSmiOperation* deferred =
5615               new DeferredInlineSmiOperation(op,
5616                                              answer.reg(),
5617                                              operand->reg(),
5618                                              smi_value,
5619                                              overwrite_mode);
5620           __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5621           __ SmiShiftLeftConstant(answer.reg(),
5622                                   operand->reg(),
5623                                   shift_value,
5624                                   deferred->entry_label());
5625           deferred->BindExit();
5626           operand->Unuse();
5627         }
5628       }
5629       break;
5630
5631     case Token::BIT_OR:
5632     case Token::BIT_XOR:
5633     case Token::BIT_AND: {
5634       operand->ToRegister();
5635       frame_->Spill(operand->reg());
5636       if (reversed) {
5637         // Bit operations with a constant smi are commutative.
5638         // We can swap left and right operands with no problem.
5639         // Swap left and right overwrite modes.  0->0, 1->2, 2->1.
5640         overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3);
5641       }
5642       DeferredCode* deferred =  new DeferredInlineSmiOperation(op,
5643                                                                operand->reg(),
5644                                                                operand->reg(),
5645                                                                smi_value,
5646                                                                overwrite_mode);
5647       __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
5648       if (op == Token::BIT_AND) {
5649         __ SmiAndConstant(operand->reg(), operand->reg(), smi_value);
5650       } else if (op == Token::BIT_XOR) {
5651         if (int_value != 0) {
5652           __ SmiXorConstant(operand->reg(), operand->reg(), smi_value);
5653         }
5654       } else {
5655         ASSERT(op == Token::BIT_OR);
5656         if (int_value != 0) {
5657           __ SmiOrConstant(operand->reg(), operand->reg(), smi_value);
5658         }
5659       }
5660       deferred->BindExit();
5661       answer = *operand;
5662       break;
5663     }
5664
5665     // Generate inline code for mod of powers of 2 and negative powers of 2.
5666     case Token::MOD:
5667       if (!reversed &&
5668           int_value != 0 &&
5669           (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) {
5670         operand->ToRegister();
5671         frame_->Spill(operand->reg());
5672         DeferredCode* deferred =
5673             new DeferredInlineSmiOperation(op,
5674                                            operand->reg(),
5675                                            operand->reg(),
5676                                            smi_value,
5677                                            overwrite_mode);
5678         // Check for negative or non-Smi left hand side.
5679         __ JumpIfNotPositiveSmi(operand->reg(), deferred->entry_label());
5680         if (int_value < 0) int_value = -int_value;
5681         if (int_value == 1) {
5682           __ Move(operand->reg(), Smi::FromInt(0));
5683         } else {
5684           __ SmiAndConstant(operand->reg(),
5685                             operand->reg(),
5686                             Smi::FromInt(int_value - 1));
5687         }
5688         deferred->BindExit();
5689         answer = *operand;
5690         break;  // This break only applies if we generated code for MOD.
5691       }
5692       // Fall through if we did not find a power of 2 on the right hand side!
5693       // The next case must be the default.
5694
5695     default: {
5696       Result constant_operand(value);
5697       if (reversed) {
5698         answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
5699                                           overwrite_mode);
5700       } else {
5701         answer = LikelySmiBinaryOperation(op, operand, &constant_operand,
5702                                           overwrite_mode);
5703       }
5704       break;
5705     }
5706   }
5707   ASSERT(answer.is_valid());
5708   return answer;
5709 }
5710
5711 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
5712                                                Result* left,
5713                                                Result* right,
5714                                                OverwriteMode overwrite_mode) {
5715   Result answer;
5716   // Special handling of div and mod because they use fixed registers.
5717   if (op == Token::DIV || op == Token::MOD) {
5718     // We need rax as the quotient register, rdx as the remainder
5719     // register, neither left nor right in rax or rdx, and left copied
5720     // to rax.
5721     Result quotient;
5722     Result remainder;
5723     bool left_is_in_rax = false;
5724     // Step 1: get rax for quotient.
5725     if ((left->is_register() && left->reg().is(rax)) ||
5726         (right->is_register() && right->reg().is(rax))) {
5727       // One or both is in rax.  Use a fresh non-rdx register for
5728       // them.
5729       Result fresh = allocator_->Allocate();
5730       ASSERT(fresh.is_valid());
5731       if (fresh.reg().is(rdx)) {
5732         remainder = fresh;
5733         fresh = allocator_->Allocate();
5734         ASSERT(fresh.is_valid());
5735       }
5736       if (left->is_register() && left->reg().is(rax)) {
5737         quotient = *left;
5738         *left = fresh;
5739         left_is_in_rax = true;
5740       }
5741       if (right->is_register() && right->reg().is(rax)) {
5742         quotient = *right;
5743         *right = fresh;
5744       }
5745       __ movq(fresh.reg(), rax);
5746     } else {
5747       // Neither left nor right is in rax.
5748       quotient = allocator_->Allocate(rax);
5749     }
5750     ASSERT(quotient.is_register() && quotient.reg().is(rax));
5751     ASSERT(!(left->is_register() && left->reg().is(rax)));
5752     ASSERT(!(right->is_register() && right->reg().is(rax)));
5753
5754     // Step 2: get rdx for remainder if necessary.
5755     if (!remainder.is_valid()) {
5756       if ((left->is_register() && left->reg().is(rdx)) ||
5757           (right->is_register() && right->reg().is(rdx))) {
5758         Result fresh = allocator_->Allocate();
5759         ASSERT(fresh.is_valid());
5760         if (left->is_register() && left->reg().is(rdx)) {
5761           remainder = *left;
5762           *left = fresh;
5763         }
5764         if (right->is_register() && right->reg().is(rdx)) {
5765           remainder = *right;
5766           *right = fresh;
5767         }
5768         __ movq(fresh.reg(), rdx);
5769       } else {
5770         // Neither left nor right is in rdx.
5771         remainder = allocator_->Allocate(rdx);
5772       }
5773     }
5774     ASSERT(remainder.is_register() && remainder.reg().is(rdx));
5775     ASSERT(!(left->is_register() && left->reg().is(rdx)));
5776     ASSERT(!(right->is_register() && right->reg().is(rdx)));
5777
5778     left->ToRegister();
5779     right->ToRegister();
5780     frame_->Spill(rax);
5781     frame_->Spill(rdx);
5782
5783     // Check that left and right are smi tagged.
5784     DeferredInlineBinaryOperation* deferred =
5785         new DeferredInlineBinaryOperation(op,
5786                                           (op == Token::DIV) ? rax : rdx,
5787                                           left->reg(),
5788                                           right->reg(),
5789                                           overwrite_mode);
5790     __ JumpIfNotBothSmi(left->reg(), right->reg(), deferred->entry_label());
5791
5792     if (op == Token::DIV) {
5793       __ SmiDiv(rax, left->reg(), right->reg(), deferred->entry_label());
5794       deferred->BindExit();
5795       left->Unuse();
5796       right->Unuse();
5797       answer = quotient;
5798     } else {
5799       ASSERT(op == Token::MOD);
5800       __ SmiMod(rdx, left->reg(), right->reg(), deferred->entry_label());
5801       deferred->BindExit();
5802       left->Unuse();
5803       right->Unuse();
5804       answer = remainder;
5805     }
5806     ASSERT(answer.is_valid());
5807     return answer;
5808   }
5809
5810   // Special handling of shift operations because they use fixed
5811   // registers.
5812   if (op == Token::SHL || op == Token::SHR || op == Token::SAR) {
5813     // Move left out of rcx if necessary.
5814     if (left->is_register() && left->reg().is(rcx)) {
5815       *left = allocator_->Allocate();
5816       ASSERT(left->is_valid());
5817       __ movq(left->reg(), rcx);
5818     }
5819     right->ToRegister(rcx);
5820     left->ToRegister();
5821     ASSERT(left->is_register() && !left->reg().is(rcx));
5822     ASSERT(right->is_register() && right->reg().is(rcx));
5823
5824     // We will modify right, it must be spilled.
5825     frame_->Spill(rcx);
5826
5827     // Use a fresh answer register to avoid spilling the left operand.
5828     answer = allocator_->Allocate();
5829     ASSERT(answer.is_valid());
5830     // Check that both operands are smis using the answer register as a
5831     // temporary.
5832     DeferredInlineBinaryOperation* deferred =
5833         new DeferredInlineBinaryOperation(op,
5834                                           answer.reg(),
5835                                           left->reg(),
5836                                           rcx,
5837                                           overwrite_mode);
5838     __ movq(answer.reg(), left->reg());
5839     __ or_(answer.reg(), rcx);
5840     __ JumpIfNotSmi(answer.reg(), deferred->entry_label());
5841
5842     // Perform the operation.
5843     switch (op) {
5844       case Token::SAR:
5845         __ SmiShiftArithmeticRight(answer.reg(), left->reg(), rcx);
5846         break;
5847       case Token::SHR: {
5848         __ SmiShiftLogicalRight(answer.reg(),
5849                               left->reg(),
5850                               rcx,
5851                               deferred->entry_label());
5852         break;
5853       }
5854       case Token::SHL: {
5855         __ SmiShiftLeft(answer.reg(),
5856                         left->reg(),
5857                         rcx,
5858                         deferred->entry_label());
5859         break;
5860       }
5861       default:
5862         UNREACHABLE();
5863     }
5864     deferred->BindExit();
5865     left->Unuse();
5866     right->Unuse();
5867     ASSERT(answer.is_valid());
5868     return answer;
5869   }
5870
5871   // Handle the other binary operations.
5872   left->ToRegister();
5873   right->ToRegister();
5874   // A newly allocated register answer is used to hold the answer.  The
5875   // registers containing left and right are not modified so they don't
5876   // need to be spilled in the fast case.
5877   answer = allocator_->Allocate();
5878   ASSERT(answer.is_valid());
5879
5880   // Perform the smi tag check.
5881   DeferredInlineBinaryOperation* deferred =
5882       new DeferredInlineBinaryOperation(op,
5883                                         answer.reg(),
5884                                         left->reg(),
5885                                         right->reg(),
5886                                         overwrite_mode);
5887   __ JumpIfNotBothSmi(left->reg(), right->reg(), deferred->entry_label());
5888
5889   switch (op) {
5890     case Token::ADD:
5891       __ SmiAdd(answer.reg(),
5892                 left->reg(),
5893                 right->reg(),
5894                 deferred->entry_label());
5895       break;
5896
5897     case Token::SUB:
5898       __ SmiSub(answer.reg(),
5899                 left->reg(),
5900                 right->reg(),
5901                 deferred->entry_label());
5902       break;
5903
5904     case Token::MUL: {
5905       __ SmiMul(answer.reg(),
5906                 left->reg(),
5907                 right->reg(),
5908                 deferred->entry_label());
5909       break;
5910     }
5911
5912     case Token::BIT_OR:
5913       __ SmiOr(answer.reg(), left->reg(), right->reg());
5914       break;
5915
5916     case Token::BIT_AND:
5917       __ SmiAnd(answer.reg(), left->reg(), right->reg());
5918       break;
5919
5920     case Token::BIT_XOR:
5921       __ SmiXor(answer.reg(), left->reg(), right->reg());
5922       break;
5923
5924     default:
5925       UNREACHABLE();
5926       break;
5927   }
5928   deferred->BindExit();
5929   left->Unuse();
5930   right->Unuse();
5931   ASSERT(answer.is_valid());
5932   return answer;
5933 }
5934
5935
5936 Result CodeGenerator::EmitKeyedLoad(bool is_global) {
5937   Comment cmnt(masm_, "[ Load from keyed Property");
5938   // Inline array load code if inside of a loop.  We do not know
5939   // the receiver map yet, so we initially generate the code with
5940   // a check against an invalid map.  In the inline cache code, we
5941   // patch the map check if appropriate.
5942   if (loop_nesting() > 0) {
5943     Comment cmnt(masm_, "[ Inlined load from keyed Property");
5944
5945     Result key = frame_->Pop();
5946     Result receiver = frame_->Pop();
5947     key.ToRegister();
5948     receiver.ToRegister();
5949
5950     // Use a fresh temporary to load the elements without destroying
5951     // the receiver which is needed for the deferred slow case.
5952     Result elements = allocator()->Allocate();
5953     ASSERT(elements.is_valid());
5954
5955     // Use a fresh temporary for the index and later the loaded
5956     // value.
5957     Result index = allocator()->Allocate();
5958     ASSERT(index.is_valid());
5959
5960     DeferredReferenceGetKeyedValue* deferred =
5961         new DeferredReferenceGetKeyedValue(index.reg(),
5962                                            receiver.reg(),
5963                                            key.reg(),
5964                                            is_global);
5965
5966     // Check that the receiver is not a smi (only needed if this
5967     // is not a load from the global context) and that it has the
5968     // expected map.
5969     if (!is_global) {
5970       __ JumpIfSmi(receiver.reg(), deferred->entry_label());
5971     }
5972
5973     // Initially, use an invalid map. The map is patched in the IC
5974     // initialization code.
5975     __ bind(deferred->patch_site());
5976     // Use masm-> here instead of the double underscore macro since extra
5977     // coverage code can interfere with the patching.  Do not use
5978     // root array to load null_value, since it must be patched with
5979     // the expected receiver map.
5980     masm_->movq(kScratchRegister, Factory::null_value(),
5981                 RelocInfo::EMBEDDED_OBJECT);
5982     masm_->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
5983                 kScratchRegister);
5984     deferred->Branch(not_equal);
5985
5986     // Check that the key is a non-negative smi.
5987     __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label());
5988
5989     // Get the elements array from the receiver and check that it
5990     // is not a dictionary.
5991     __ movq(elements.reg(),
5992             FieldOperand(receiver.reg(), JSObject::kElementsOffset));
5993     __ Cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset),
5994            Factory::fixed_array_map());
5995     deferred->Branch(not_equal);
5996
5997     // Shift the key to get the actual index value and check that
5998     // it is within bounds.
5999     __ SmiToInteger32(index.reg(), key.reg());
6000     __ cmpl(index.reg(),
6001             FieldOperand(elements.reg(), FixedArray::kLengthOffset));
6002     deferred->Branch(above_equal);
6003
6004     // The index register holds the un-smi-tagged key. It has been
6005     // zero-extended to 64-bits, so it can be used directly as index in the
6006     // operand below.
6007     // Load and check that the result is not the hole.  We could
6008     // reuse the index or elements register for the value.
6009     //
6010     // TODO(206): Consider whether it makes sense to try some
6011     // heuristic about which register to reuse.  For example, if
6012     // one is rax, the we can reuse that one because the value
6013     // coming from the deferred code will be in rax.
6014     Result value = index;
6015     __ movq(value.reg(),
6016             Operand(elements.reg(),
6017                     index.reg(),
6018                     times_pointer_size,
6019                     FixedArray::kHeaderSize - kHeapObjectTag));
6020     elements.Unuse();
6021     index.Unuse();
6022     __ CompareRoot(value.reg(), Heap::kTheHoleValueRootIndex);
6023     deferred->Branch(equal);
6024     __ IncrementCounter(&Counters::keyed_load_inline, 1);
6025
6026     deferred->BindExit();
6027     // Restore the receiver and key to the frame and push the
6028     // result on top of it.
6029     frame_->Push(&receiver);
6030     frame_->Push(&key);
6031     return value;
6032
6033   } else {
6034     Comment cmnt(masm_, "[ Load from keyed Property");
6035     RelocInfo::Mode mode = is_global
6036         ? RelocInfo::CODE_TARGET_CONTEXT
6037         : RelocInfo::CODE_TARGET;
6038     Result answer = frame_->CallKeyedLoadIC(mode);
6039     // Make sure that we do not have a test instruction after the
6040     // call.  A test instruction after the call is used to
6041     // indicate that we have generated an inline version of the
6042     // keyed load.  The explicit nop instruction is here because
6043     // the push that follows might be peep-hole optimized away.
6044     __ nop();
6045     return answer;
6046   }
6047 }
6048
6049
6050 #undef __
6051 #define __ ACCESS_MASM(masm)
6052
6053
6054 Handle<String> Reference::GetName() {
6055   ASSERT(type_ == NAMED);
6056   Property* property = expression_->AsProperty();
6057   if (property == NULL) {
6058     // Global variable reference treated as a named property reference.
6059     VariableProxy* proxy = expression_->AsVariableProxy();
6060     ASSERT(proxy->AsVariable() != NULL);
6061     ASSERT(proxy->AsVariable()->is_global());
6062     return proxy->name();
6063   } else {
6064     Literal* raw_name = property->key()->AsLiteral();
6065     ASSERT(raw_name != NULL);
6066     return Handle<String>(String::cast(*raw_name->handle()));
6067   }
6068 }
6069
6070
6071 void Reference::GetValue() {
6072   ASSERT(!cgen_->in_spilled_code());
6073   ASSERT(cgen_->HasValidEntryRegisters());
6074   ASSERT(!is_illegal());
6075   MacroAssembler* masm = cgen_->masm();
6076
6077   // Record the source position for the property load.
6078   Property* property = expression_->AsProperty();
6079   if (property != NULL) {
6080     cgen_->CodeForSourcePosition(property->position());
6081   }
6082
6083   switch (type_) {
6084     case SLOT: {
6085       Comment cmnt(masm, "[ Load from Slot");
6086       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
6087       ASSERT(slot != NULL);
6088       cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
6089       break;
6090     }
6091
6092     case NAMED: {
6093       Variable* var = expression_->AsVariableProxy()->AsVariable();
6094       bool is_global = var != NULL;
6095       ASSERT(!is_global || var->is_global());
6096
6097       // Do not inline the inobject property case for loads from the global
6098       // object.  Also do not inline for unoptimized code.  This saves time
6099       // in the code generator.  Unoptimized code is toplevel code or code
6100       // that is not in a loop.
6101       if (is_global ||
6102           cgen_->scope()->is_global_scope() ||
6103           cgen_->loop_nesting() == 0) {
6104         Comment cmnt(masm, "[ Load from named Property");
6105         cgen_->frame()->Push(GetName());
6106
6107         RelocInfo::Mode mode = is_global
6108                                ? RelocInfo::CODE_TARGET_CONTEXT
6109                                : RelocInfo::CODE_TARGET;
6110         Result answer = cgen_->frame()->CallLoadIC(mode);
6111         // A test rax instruction following the call signals that the
6112         // inobject property case was inlined.  Ensure that there is not
6113         // a test rax instruction here.
6114         __ nop();
6115         cgen_->frame()->Push(&answer);
6116       } else {
6117         // Inline the inobject property case.
6118         Comment cmnt(masm, "[ Inlined named property load");
6119         Result receiver = cgen_->frame()->Pop();
6120         receiver.ToRegister();
6121         Result value = cgen_->allocator()->Allocate();
6122         ASSERT(value.is_valid());
6123         // Cannot use r12 for receiver, because that changes
6124         // the distance between a call and a fixup location,
6125         // due to a special encoding of r12 as r/m in a ModR/M byte.
6126         if (receiver.reg().is(r12)) {
6127           // Swap receiver and value.
6128           __ movq(value.reg(), receiver.reg());
6129           Result temp = receiver;
6130           receiver = value;
6131           value = temp;
6132           cgen_->frame()->Spill(value.reg());  // r12 may have been shared.
6133         }
6134
6135         DeferredReferenceGetNamedValue* deferred =
6136             new DeferredReferenceGetNamedValue(value.reg(),
6137                                                receiver.reg(),
6138                                                GetName());
6139
6140         // Check that the receiver is a heap object.
6141         __ JumpIfSmi(receiver.reg(), deferred->entry_label());
6142
6143         __ bind(deferred->patch_site());
6144         // This is the map check instruction that will be patched (so we can't
6145         // use the double underscore macro that may insert instructions).
6146         // Initially use an invalid map to force a failure.
6147         masm->Move(kScratchRegister, Factory::null_value());
6148         masm->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
6149                    kScratchRegister);
6150         // This branch is always a forwards branch so it's always a fixed
6151         // size which allows the assert below to succeed and patching to work.
6152         // Don't use deferred->Branch(...), since that might add coverage code.
6153         masm->j(not_equal, deferred->entry_label());
6154
6155         // The delta from the patch label to the load offset must be
6156         // statically known.
6157         ASSERT(masm->SizeOfCodeGeneratedSince(deferred->patch_site()) ==
6158                LoadIC::kOffsetToLoadInstruction);
6159         // The initial (invalid) offset has to be large enough to force
6160         // a 32-bit instruction encoding to allow patching with an
6161         // arbitrary offset.  Use kMaxInt (minus kHeapObjectTag).
6162         int offset = kMaxInt;
6163         masm->movq(value.reg(), FieldOperand(receiver.reg(), offset));
6164
6165         __ IncrementCounter(&Counters::named_load_inline, 1);
6166         deferred->BindExit();
6167         cgen_->frame()->Push(&receiver);
6168         cgen_->frame()->Push(&value);
6169       }
6170       break;
6171     }
6172
6173     case KEYED: {
6174       Comment cmnt(masm, "[ Load from keyed Property");
6175       Variable* var = expression_->AsVariableProxy()->AsVariable();
6176       bool is_global = var != NULL;
6177       ASSERT(!is_global || var->is_global());
6178
6179       Result value = cgen_->EmitKeyedLoad(is_global);
6180       cgen_->frame()->Push(&value);
6181       break;
6182     }
6183
6184     default:
6185       UNREACHABLE();
6186   }
6187
6188   if (!persist_after_get_) {
6189     cgen_->UnloadReference(this);
6190   }
6191 }
6192
6193
6194 void Reference::TakeValue() {
6195   // TODO(X64): This function is completely architecture independent. Move
6196   // it somewhere shared.
6197
6198   // For non-constant frame-allocated slots, we invalidate the value in the
6199   // slot.  For all others, we fall back on GetValue.
6200   ASSERT(!cgen_->in_spilled_code());
6201   ASSERT(!is_illegal());
6202   if (type_ != SLOT) {
6203     GetValue();
6204     return;
6205   }
6206
6207   Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
6208   ASSERT(slot != NULL);
6209   if (slot->type() == Slot::LOOKUP ||
6210       slot->type() == Slot::CONTEXT ||
6211       slot->var()->mode() == Variable::CONST ||
6212       slot->is_arguments()) {
6213     GetValue();
6214     return;
6215   }
6216
6217   // Only non-constant, frame-allocated parameters and locals can reach
6218   // here.  Be careful not to use the optimizations for arguments
6219   // object access since it may not have been initialized yet.
6220   ASSERT(!slot->is_arguments());
6221   if (slot->type() == Slot::PARAMETER) {
6222     cgen_->frame()->TakeParameterAt(slot->index());
6223   } else {
6224     ASSERT(slot->type() == Slot::LOCAL);
6225     cgen_->frame()->TakeLocalAt(slot->index());
6226   }
6227
6228   ASSERT(persist_after_get_);
6229   // Do not unload the reference, because it is used in SetValue.
6230 }
6231
6232
6233 void Reference::SetValue(InitState init_state) {
6234   ASSERT(cgen_->HasValidEntryRegisters());
6235   ASSERT(!is_illegal());
6236   MacroAssembler* masm = cgen_->masm();
6237   switch (type_) {
6238     case SLOT: {
6239       Comment cmnt(masm, "[ Store to Slot");
6240       Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
6241       ASSERT(slot != NULL);
6242       cgen_->StoreToSlot(slot, init_state);
6243       cgen_->UnloadReference(this);
6244       break;
6245     }
6246
6247     case NAMED: {
6248       Comment cmnt(masm, "[ Store to named Property");
6249       cgen_->frame()->Push(GetName());
6250       Result answer = cgen_->frame()->CallStoreIC();
6251       cgen_->frame()->Push(&answer);
6252       set_unloaded();
6253       break;
6254     }
6255
6256     case KEYED: {
6257       Comment cmnt(masm, "[ Store to keyed Property");
6258
6259       // Generate inlined version of the keyed store if the code is in
6260       // a loop and the key is likely to be a smi.
6261       Property* property = expression()->AsProperty();
6262       ASSERT(property != NULL);
6263       StaticType* key_smi_analysis = property->key()->type();
6264
6265       if (cgen_->loop_nesting() > 0 && key_smi_analysis->IsLikelySmi()) {
6266         Comment cmnt(masm, "[ Inlined store to keyed Property");
6267
6268         // Get the receiver, key and value into registers.
6269         Result value = cgen_->frame()->Pop();
6270         Result key = cgen_->frame()->Pop();
6271         Result receiver = cgen_->frame()->Pop();
6272
6273         Result tmp = cgen_->allocator_->Allocate();
6274         ASSERT(tmp.is_valid());
6275
6276         // Determine whether the value is a constant before putting it
6277         // in a register.
6278         bool value_is_constant = value.is_constant();
6279
6280         // Make sure that value, key and receiver are in registers.
6281         value.ToRegister();
6282         key.ToRegister();
6283         receiver.ToRegister();
6284
6285         DeferredReferenceSetKeyedValue* deferred =
6286             new DeferredReferenceSetKeyedValue(value.reg(),
6287                                                key.reg(),
6288                                                receiver.reg());
6289
6290         // Check that the value is a smi if it is not a constant.
6291         // We can skip the write barrier for smis and constants.
6292         if (!value_is_constant) {
6293           __ JumpIfNotSmi(value.reg(), deferred->entry_label());
6294         }
6295
6296         // Check that the key is a non-negative smi.
6297         __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label());
6298
6299         // Check that the receiver is not a smi.
6300         __ JumpIfSmi(receiver.reg(), deferred->entry_label());
6301
6302         // Check that the receiver is a JSArray.
6303         __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister);
6304         deferred->Branch(not_equal);
6305
6306         // Check that the key is within bounds.  Both the key and the
6307         // length of the JSArray are smis.
6308         __ SmiCompare(FieldOperand(receiver.reg(), JSArray::kLengthOffset),
6309                       key.reg());
6310         deferred->Branch(less_equal);
6311
6312         // Get the elements array from the receiver and check that it
6313         // is a flat array (not a dictionary).
6314         __ movq(tmp.reg(),
6315                 FieldOperand(receiver.reg(), JSObject::kElementsOffset));
6316         // Bind the deferred code patch site to be able to locate the
6317         // fixed array map comparison.  When debugging, we patch this
6318         // comparison to always fail so that we will hit the IC call
6319         // in the deferred code which will allow the debugger to
6320         // break for fast case stores.
6321         __ bind(deferred->patch_site());
6322         // Avoid using __ to ensure the distance from patch_site
6323         // to the map address is always the same.
6324         masm->movq(kScratchRegister, Factory::fixed_array_map(),
6325                    RelocInfo::EMBEDDED_OBJECT);
6326         __ cmpq(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
6327                 kScratchRegister);
6328         deferred->Branch(not_equal);
6329
6330         // Store the value.
6331         SmiIndex index =
6332             masm->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2);
6333               __ movq(Operand(tmp.reg(),
6334                         index.reg,
6335                         index.scale,
6336                         FixedArray::kHeaderSize - kHeapObjectTag),
6337                 value.reg());
6338         __ IncrementCounter(&Counters::keyed_store_inline, 1);
6339
6340         deferred->BindExit();
6341
6342         cgen_->frame()->Push(&receiver);
6343         cgen_->frame()->Push(&key);
6344         cgen_->frame()->Push(&value);
6345       } else {
6346         Result answer = cgen_->frame()->CallKeyedStoreIC();
6347         // Make sure that we do not have a test instruction after the
6348         // call.  A test instruction after the call is used to
6349         // indicate that we have generated an inline version of the
6350         // keyed store.
6351         masm->nop();
6352         cgen_->frame()->Push(&answer);
6353       }
6354       cgen_->UnloadReference(this);
6355       break;
6356     }
6357
6358     default:
6359       UNREACHABLE();
6360   }
6361 }
6362
6363
6364 void FastNewClosureStub::Generate(MacroAssembler* masm) {
6365   // Create a new closure from the given function info in new
6366   // space. Set the context to the current context in rsi.
6367   Label gc;
6368   __ AllocateInNewSpace(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
6369
6370   // Get the function info from the stack.
6371   __ movq(rdx, Operand(rsp, 1 * kPointerSize));
6372
6373   // Compute the function map in the current global context and set that
6374   // as the map of the allocated object.
6375   __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
6376   __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset));
6377   __ movq(rcx, Operand(rcx, Context::SlotOffset(Context::FUNCTION_MAP_INDEX)));
6378   __ movq(FieldOperand(rax, JSObject::kMapOffset), rcx);
6379
6380   // Initialize the rest of the function. We don't have to update the
6381   // write barrier because the allocated object is in new space.
6382   __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
6383   __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex);
6384   __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
6385   __ movq(FieldOperand(rax, JSObject::kElementsOffset), rbx);
6386   __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), rcx);
6387   __ movq(FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset), rdx);
6388   __ movq(FieldOperand(rax, JSFunction::kContextOffset), rsi);
6389   __ movq(FieldOperand(rax, JSFunction::kLiteralsOffset), rbx);
6390
6391   // Return and remove the on-stack parameter.
6392   __ ret(1 * kPointerSize);
6393
6394   // Create a new closure through the slower runtime call.
6395   __ bind(&gc);
6396   __ pop(rcx);  // Temporarily remove return address.
6397   __ pop(rdx);
6398   __ push(rsi);
6399   __ push(rdx);
6400   __ push(rcx);  // Restore return address.
6401   __ TailCallRuntime(Runtime::kNewClosure, 2, 1);
6402 }
6403
6404
6405 void FastNewContextStub::Generate(MacroAssembler* masm) {
6406   // Try to allocate the context in new space.
6407   Label gc;
6408   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
6409   __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
6410                         rax, rbx, rcx, &gc, TAG_OBJECT);
6411
6412   // Get the function from the stack.
6413   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
6414
6415   // Setup the object header.
6416   __ LoadRoot(kScratchRegister, Heap::kContextMapRootIndex);
6417   __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
6418   __ movl(FieldOperand(rax, Array::kLengthOffset), Immediate(length));
6419
6420   // Setup the fixed slots.
6421   __ xor_(rbx, rbx);  // Set to NULL.
6422   __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
6423   __ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax);
6424   __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx);
6425   __ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx);
6426
6427   // Copy the global object from the surrounding context.
6428   __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
6429   __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);
6430
6431   // Initialize the rest of the slots to undefined.
6432   __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
6433   for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
6434     __ movq(Operand(rax, Context::SlotOffset(i)), rbx);
6435   }
6436
6437   // Return and remove the on-stack parameter.
6438   __ movq(rsi, rax);
6439   __ ret(1 * kPointerSize);
6440
6441   // Need to collect. Call into runtime system.
6442   __ bind(&gc);
6443   __ TailCallRuntime(Runtime::kNewContext, 1, 1);
6444 }
6445
6446
6447 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
6448   // Stack layout on entry:
6449   //
6450   // [rsp + kPointerSize]: constant elements.
6451   // [rsp + (2 * kPointerSize)]: literal index.
6452   // [rsp + (3 * kPointerSize)]: literals array.
6453
6454   // All sizes here are multiples of kPointerSize.
6455   int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
6456   int size = JSArray::kSize + elements_size;
6457
6458   // Load boilerplate object into rcx and check if we need to create a
6459   // boilerplate.
6460   Label slow_case;
6461   __ movq(rcx, Operand(rsp, 3 * kPointerSize));
6462   __ movq(rax, Operand(rsp, 2 * kPointerSize));
6463   SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
6464   __ movq(rcx,
6465           FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize));
6466   __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
6467   __ j(equal, &slow_case);
6468
6469   // Allocate both the JS array and the elements array in one big
6470   // allocation. This avoids multiple limit checks.
6471   __ AllocateInNewSpace(size, rax, rbx, rdx, &slow_case, TAG_OBJECT);
6472
6473   // Copy the JS array part.
6474   for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
6475     if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
6476       __ movq(rbx, FieldOperand(rcx, i));
6477       __ movq(FieldOperand(rax, i), rbx);
6478     }
6479   }
6480
6481   if (length_ > 0) {
6482     // Get hold of the elements array of the boilerplate and setup the
6483     // elements pointer in the resulting object.
6484     __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
6485     __ lea(rdx, Operand(rax, JSArray::kSize));
6486     __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx);
6487
6488     // Copy the elements array.
6489     for (int i = 0; i < elements_size; i += kPointerSize) {
6490       __ movq(rbx, FieldOperand(rcx, i));
6491       __ movq(FieldOperand(rdx, i), rbx);
6492     }
6493   }
6494
6495   // Return and remove the on-stack parameters.
6496   __ ret(3 * kPointerSize);
6497
6498   __ bind(&slow_case);
6499   __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1);
6500 }
6501
6502
6503 void ToBooleanStub::Generate(MacroAssembler* masm) {
6504   Label false_result, true_result, not_string;
6505   __ movq(rax, Operand(rsp, 1 * kPointerSize));
6506
6507   // 'null' => false.
6508   __ CompareRoot(rax, Heap::kNullValueRootIndex);
6509   __ j(equal, &false_result);
6510
6511   // Get the map and type of the heap object.
6512   // We don't use CmpObjectType because we manipulate the type field.
6513   __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
6514   __ movzxbq(rcx, FieldOperand(rdx, Map::kInstanceTypeOffset));
6515
6516   // Undetectable => false.
6517   __ movzxbq(rbx, FieldOperand(rdx, Map::kBitFieldOffset));
6518   __ and_(rbx, Immediate(1 << Map::kIsUndetectable));
6519   __ j(not_zero, &false_result);
6520
6521   // JavaScript object => true.
6522   __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE));
6523   __ j(above_equal, &true_result);
6524
6525   // String value => false iff empty.
6526   __ cmpq(rcx, Immediate(FIRST_NONSTRING_TYPE));
6527   __ j(above_equal, &not_string);
6528   __ movl(rdx, FieldOperand(rax, String::kLengthOffset));
6529   __ testl(rdx, rdx);
6530   __ j(zero, &false_result);
6531   __ jmp(&true_result);
6532
6533   __ bind(&not_string);
6534   // HeapNumber => false iff +0, -0, or NaN.
6535   // These three cases set C3 when compared to zero in the FPU.
6536   __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
6537   __ j(not_equal, &true_result);
6538   __ fldz();  // Load zero onto fp stack
6539   // Load heap-number double value onto fp stack
6540   __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset));
6541   __ FCmp();
6542   __ j(zero, &false_result);
6543   // Fall through to |true_result|.
6544
6545   // Return 1/0 for true/false in rax.
6546   __ bind(&true_result);
6547   __ movq(rax, Immediate(1));
6548   __ ret(1 * kPointerSize);
6549   __ bind(&false_result);
6550   __ xor_(rax, rax);
6551   __ ret(1 * kPointerSize);
6552 }
6553
6554
6555 bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) {
6556   Object* answer_object = Heap::undefined_value();
6557   switch (op) {
6558     case Token::ADD:
6559       // Use intptr_t to detect overflow of 32-bit int.
6560       if (Smi::IsValid(static_cast<intptr_t>(left) + right)) {
6561         answer_object = Smi::FromInt(left + right);
6562       }
6563       break;
6564     case Token::SUB:
6565       // Use intptr_t to detect overflow of 32-bit int.
6566       if (Smi::IsValid(static_cast<intptr_t>(left) - right)) {
6567         answer_object = Smi::FromInt(left - right);
6568       }
6569       break;
6570     case Token::MUL: {
6571         double answer = static_cast<double>(left) * right;
6572         if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) {
6573           // If the product is zero and the non-zero factor is negative,
6574           // the spec requires us to return floating point negative zero.
6575           if (answer != 0 || (left + right) >= 0) {
6576             answer_object = Smi::FromInt(static_cast<int>(answer));
6577           }
6578         }
6579       }
6580       break;
6581     case Token::DIV:
6582     case Token::MOD:
6583       break;
6584     case Token::BIT_OR:
6585       answer_object = Smi::FromInt(left | right);
6586       break;
6587     case Token::BIT_AND:
6588       answer_object = Smi::FromInt(left & right);
6589       break;
6590     case Token::BIT_XOR:
6591       answer_object = Smi::FromInt(left ^ right);
6592       break;
6593
6594     case Token::SHL: {
6595         int shift_amount = right & 0x1F;
6596         if (Smi::IsValid(left << shift_amount)) {
6597           answer_object = Smi::FromInt(left << shift_amount);
6598         }
6599         break;
6600       }
6601     case Token::SHR: {
6602         int shift_amount = right & 0x1F;
6603         unsigned int unsigned_left = left;
6604         unsigned_left >>= shift_amount;
6605         if (unsigned_left <= static_cast<unsigned int>(Smi::kMaxValue)) {
6606           answer_object = Smi::FromInt(unsigned_left);
6607         }
6608         break;
6609       }
6610     case Token::SAR: {
6611         int shift_amount = right & 0x1F;
6612         unsigned int unsigned_left = left;
6613         if (left < 0) {
6614           // Perform arithmetic shift of a negative number by
6615           // complementing number, logical shifting, complementing again.
6616           unsigned_left = ~unsigned_left;
6617           unsigned_left >>= shift_amount;
6618           unsigned_left = ~unsigned_left;
6619         } else {
6620           unsigned_left >>= shift_amount;
6621         }
6622         ASSERT(Smi::IsValid(static_cast<int32_t>(unsigned_left)));
6623         answer_object = Smi::FromInt(static_cast<int32_t>(unsigned_left));
6624         break;
6625       }
6626     default:
6627       UNREACHABLE();
6628       break;
6629   }
6630   if (answer_object == Heap::undefined_value()) {
6631     return false;
6632   }
6633   frame_->Push(Handle<Object>(answer_object));
6634   return true;
6635 }
6636
6637
6638 // End of CodeGenerator implementation.
6639
6640 // Get the integer part of a heap number.  Surprisingly, all this bit twiddling
6641 // is faster than using the built-in instructions on floating point registers.
6642 // Trashes rdi and rbx.  Dest is rcx.  Source cannot be rcx or one of the
6643 // trashed registers.
6644 void IntegerConvert(MacroAssembler* masm,
6645                     Register source,
6646                     bool use_sse3,
6647                     Label* conversion_failure) {
6648   ASSERT(!source.is(rcx) && !source.is(rdi) && !source.is(rbx));
6649   Label done, right_exponent, normal_exponent;
6650   Register scratch = rbx;
6651   Register scratch2 = rdi;
6652   // Get exponent word.
6653   __ movl(scratch, FieldOperand(source, HeapNumber::kExponentOffset));
6654   // Get exponent alone in scratch2.
6655   __ movl(scratch2, scratch);
6656   __ and_(scratch2, Immediate(HeapNumber::kExponentMask));
6657   if (use_sse3) {
6658     CpuFeatures::Scope scope(SSE3);
6659     // Check whether the exponent is too big for a 64 bit signed integer.
6660     static const uint32_t kTooBigExponent =
6661         (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
6662     __ cmpl(scratch2, Immediate(kTooBigExponent));
6663     __ j(greater_equal, conversion_failure);
6664     // Load x87 register with heap number.
6665     __ fld_d(FieldOperand(source, HeapNumber::kValueOffset));
6666     // Reserve space for 64 bit answer.
6667     __ subq(rsp, Immediate(sizeof(uint64_t)));  // Nolint.
6668     // Do conversion, which cannot fail because we checked the exponent.
6669     __ fisttp_d(Operand(rsp, 0));
6670     __ movl(rcx, Operand(rsp, 0));  // Load low word of answer into rcx.
6671     __ addq(rsp, Immediate(sizeof(uint64_t)));  // Nolint.
6672   } else {
6673     // Load rcx with zero.  We use this either for the final shift or
6674     // for the answer.
6675     __ xor_(rcx, rcx);
6676     // Check whether the exponent matches a 32 bit signed int that cannot be
6677     // represented by a Smi.  A non-smi 32 bit integer is 1.xxx * 2^30 so the
6678     // exponent is 30 (biased).  This is the exponent that we are fastest at and
6679     // also the highest exponent we can handle here.
6680     const uint32_t non_smi_exponent =
6681         (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
6682     __ cmpl(scratch2, Immediate(non_smi_exponent));
6683     // If we have a match of the int32-but-not-Smi exponent then skip some
6684     // logic.
6685     __ j(equal, &right_exponent);
6686     // If the exponent is higher than that then go to slow case.  This catches
6687     // numbers that don't fit in a signed int32, infinities and NaNs.
6688     __ j(less, &normal_exponent);
6689
6690     {
6691       // Handle a big exponent.  The only reason we have this code is that the
6692       // >>> operator has a tendency to generate numbers with an exponent of 31.
6693       const uint32_t big_non_smi_exponent =
6694           (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift;
6695       __ cmpl(scratch2, Immediate(big_non_smi_exponent));
6696       __ j(not_equal, conversion_failure);
6697       // We have the big exponent, typically from >>>.  This means the number is
6698       // in the range 2^31 to 2^32 - 1.  Get the top bits of the mantissa.
6699       __ movl(scratch2, scratch);
6700       __ and_(scratch2, Immediate(HeapNumber::kMantissaMask));
6701       // Put back the implicit 1.
6702       __ or_(scratch2, Immediate(1 << HeapNumber::kExponentShift));
6703       // Shift up the mantissa bits to take up the space the exponent used to
6704       // take. We just orred in the implicit bit so that took care of one and
6705       // we want to use the full unsigned range so we subtract 1 bit from the
6706       // shift distance.
6707       const int big_shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1;
6708       __ shl(scratch2, Immediate(big_shift_distance));
6709       // Get the second half of the double.
6710       __ movl(rcx, FieldOperand(source, HeapNumber::kMantissaOffset));
6711       // Shift down 21 bits to get the most significant 11 bits or the low
6712       // mantissa word.
6713       __ shr(rcx, Immediate(32 - big_shift_distance));
6714       __ or_(rcx, scratch2);
6715       // We have the answer in rcx, but we may need to negate it.
6716       __ testl(scratch, scratch);
6717       __ j(positive, &done);
6718       __ neg(rcx);
6719       __ jmp(&done);
6720     }
6721
6722     __ bind(&normal_exponent);
6723     // Exponent word in scratch, exponent part of exponent word in scratch2.
6724     // Zero in rcx.
6725     // We know the exponent is smaller than 30 (biased).  If it is less than
6726     // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie
6727     // it rounds to zero.
6728     const uint32_t zero_exponent =
6729         (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift;
6730     __ subl(scratch2, Immediate(zero_exponent));
6731     // rcx already has a Smi zero.
6732     __ j(less, &done);
6733
6734     // We have a shifted exponent between 0 and 30 in scratch2.
6735     __ shr(scratch2, Immediate(HeapNumber::kExponentShift));
6736     __ movl(rcx, Immediate(30));
6737     __ subl(rcx, scratch2);
6738
6739     __ bind(&right_exponent);
6740     // Here rcx is the shift, scratch is the exponent word.
6741     // Get the top bits of the mantissa.
6742     __ and_(scratch, Immediate(HeapNumber::kMantissaMask));
6743     // Put back the implicit 1.
6744     __ or_(scratch, Immediate(1 << HeapNumber::kExponentShift));
6745     // Shift up the mantissa bits to take up the space the exponent used to
6746     // take. We have kExponentShift + 1 significant bits int he low end of the
6747     // word.  Shift them to the top bits.
6748     const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
6749     __ shl(scratch, Immediate(shift_distance));
6750     // Get the second half of the double. For some exponents we don't
6751     // actually need this because the bits get shifted out again, but
6752     // it's probably slower to test than just to do it.
6753     __ movl(scratch2, FieldOperand(source, HeapNumber::kMantissaOffset));
6754     // Shift down 22 bits to get the most significant 10 bits or the low
6755     // mantissa word.
6756     __ shr(scratch2, Immediate(32 - shift_distance));
6757     __ or_(scratch2, scratch);
6758     // Move down according to the exponent.
6759     __ shr_cl(scratch2);
6760     // Now the unsigned answer is in scratch2.  We need to move it to rcx and
6761     // we may need to fix the sign.
6762     Label negative;
6763     __ xor_(rcx, rcx);
6764     __ cmpl(rcx, FieldOperand(source, HeapNumber::kExponentOffset));
6765     __ j(greater, &negative);
6766     __ movl(rcx, scratch2);
6767     __ jmp(&done);
6768     __ bind(&negative);
6769     __ subl(rcx, scratch2);
6770     __ bind(&done);
6771   }
6772 }
6773
6774
6775 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
6776   Label slow, done;
6777
6778   if (op_ == Token::SUB) {
6779     // Check whether the value is a smi.
6780     Label try_float;
6781     __ JumpIfNotSmi(rax, &try_float);
6782
6783     // Enter runtime system if the value of the smi is zero
6784     // to make sure that we switch between 0 and -0.
6785     // Also enter it if the value of the smi is Smi::kMinValue.
6786     __ SmiNeg(rax, rax, &done);
6787
6788     // Either zero or Smi::kMinValue, neither of which become a smi when
6789     // negated.
6790     __ SmiCompare(rax, Smi::FromInt(0));
6791     __ j(not_equal, &slow);
6792     __ Move(rax, Factory::minus_zero_value());
6793     __ jmp(&done);
6794
6795     // Try floating point case.
6796     __ bind(&try_float);
6797     __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
6798     __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
6799     __ j(not_equal, &slow);
6800     // Operand is a float, negate its value by flipping sign bit.
6801     __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
6802     __ movq(kScratchRegister, Immediate(0x01));
6803     __ shl(kScratchRegister, Immediate(63));
6804     __ xor_(rdx, kScratchRegister);  // Flip sign.
6805     // rdx is value to store.
6806     if (overwrite_) {
6807       __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx);
6808     } else {
6809       __ AllocateHeapNumber(rcx, rbx, &slow);
6810       // rcx: allocated 'empty' number
6811       __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
6812       __ movq(rax, rcx);
6813     }
6814   } else if (op_ == Token::BIT_NOT) {
6815     // Check if the operand is a heap number.
6816     __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
6817     __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
6818     __ j(not_equal, &slow);
6819
6820     // Convert the heap number in rax to an untagged integer in rcx.
6821     IntegerConvert(masm, rax, CpuFeatures::IsSupported(SSE3), &slow);
6822
6823     // Do the bitwise operation and check if the result fits in a smi.
6824     Label try_float;
6825     __ not_(rcx);
6826     // Tag the result as a smi and we're done.
6827     ASSERT(kSmiTagSize == 1);
6828     __ Integer32ToSmi(rax, rcx);
6829   }
6830
6831   // Return from the stub.
6832   __ bind(&done);
6833   __ StubReturn(1);
6834
6835   // Handle the slow case by jumping to the JavaScript builtin.
6836   __ bind(&slow);
6837   __ pop(rcx);  // pop return address
6838   __ push(rax);
6839   __ push(rcx);  // push return address
6840   switch (op_) {
6841     case Token::SUB:
6842       __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
6843       break;
6844     case Token::BIT_NOT:
6845       __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION);
6846       break;
6847     default:
6848       UNREACHABLE();
6849   }
6850 }
6851
6852
6853 void RegExpExecStub::Generate(MacroAssembler* masm) {
6854   // Just jump directly to runtime if native RegExp is not selected at compile
6855   // time or if regexp entry in generated code is turned off runtime switch or
6856   // at compilation.
6857 #ifndef V8_NATIVE_REGEXP
6858   __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
6859 #else  // V8_NATIVE_REGEXP
6860   if (!FLAG_regexp_entry_native) {
6861     __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
6862     return;
6863   }
6864
6865   // Stack frame on entry.
6866   //  esp[0]: return address
6867   //  esp[8]: last_match_info (expected JSArray)
6868   //  esp[16]: previous index
6869   //  esp[24]: subject string
6870   //  esp[32]: JSRegExp object
6871
6872   static const int kLastMatchInfoOffset = 1 * kPointerSize;
6873   static const int kPreviousIndexOffset = 2 * kPointerSize;
6874   static const int kSubjectOffset = 3 * kPointerSize;
6875   static const int kJSRegExpOffset = 4 * kPointerSize;
6876
6877   Label runtime;
6878
6879   // Ensure that a RegExp stack is allocated.
6880   ExternalReference address_of_regexp_stack_memory_address =
6881       ExternalReference::address_of_regexp_stack_memory_address();
6882   ExternalReference address_of_regexp_stack_memory_size =
6883       ExternalReference::address_of_regexp_stack_memory_size();
6884   __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
6885   __ movq(kScratchRegister, Operand(kScratchRegister, 0));
6886   __ testq(kScratchRegister, kScratchRegister);
6887   __ j(zero, &runtime);
6888
6889
6890   // Check that the first argument is a JSRegExp object.
6891   __ movq(rax, Operand(rsp, kJSRegExpOffset));
6892   __ JumpIfSmi(rax, &runtime);
6893   __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
6894   __ j(not_equal, &runtime);
6895   // Check that the RegExp has been compiled (data contains a fixed array).
6896   __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
6897   if (FLAG_debug_code) {
6898     Condition is_smi = masm->CheckSmi(rcx);
6899     __ Check(NegateCondition(is_smi),
6900         "Unexpected type for RegExp data, FixedArray expected");
6901     __ CmpObjectType(rcx, FIXED_ARRAY_TYPE, kScratchRegister);
6902     __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
6903   }
6904
6905   // rcx: RegExp data (FixedArray)
6906   // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
6907   __ movq(rbx, FieldOperand(rcx, JSRegExp::kDataTagOffset));
6908   __ SmiCompare(rbx, Smi::FromInt(JSRegExp::IRREGEXP));
6909   __ j(not_equal, &runtime);
6910
6911   // rcx: RegExp data (FixedArray)
6912   // Check that the number of captures fit in the static offsets vector buffer.
6913   __ movq(rdx, FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
6914   // Calculate number of capture registers (number_of_captures + 1) * 2.
6915   __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rdx, 1);
6916   __ addq(rdx, Immediate(2));  // rdx was number_of_captures * 2.
6917   // Check that the static offsets vector buffer is large enough.
6918   __ cmpq(rdx, Immediate(OffsetsVector::kStaticOffsetsVectorSize));
6919   __ j(above, &runtime);
6920
6921   // rcx: RegExp data (FixedArray)
6922   // rdx: Number of capture registers
6923   // Check that the second argument is a string.
6924   __ movq(rax, Operand(rsp, kSubjectOffset));
6925   __ JumpIfSmi(rax, &runtime);
6926   Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
6927   __ j(NegateCondition(is_string), &runtime);
6928   // Get the length of the string to rbx.
6929   __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
6930
6931   // rbx: Length of subject string
6932   // rcx: RegExp data (FixedArray)
6933   // rdx: Number of capture registers
6934   // Check that the third argument is a positive smi less than the string
6935   // length. A negative value will be greater (usigned comparison).
6936   __ movq(rax, Operand(rsp, kPreviousIndexOffset));
6937   __ SmiToInteger32(rax, rax);
6938   __ cmpl(rax, rbx);
6939   __ j(above, &runtime);
6940
6941   // rcx: RegExp data (FixedArray)
6942   // rdx: Number of capture registers
6943   // Check that the fourth object is a JSArray object.
6944   __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
6945   __ JumpIfSmi(rax, &runtime);
6946   __ CmpObjectType(rax, JS_ARRAY_TYPE, kScratchRegister);
6947   __ j(not_equal, &runtime);
6948   // Check that the JSArray is in fast case.
6949   __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset));
6950   __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset));
6951   __ Cmp(rax, Factory::fixed_array_map());
6952   __ j(not_equal, &runtime);
6953   // Check that the last match info has space for the capture registers and the
6954   // additional information. Ensure no overflow in add.
6955   ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
6956   __ movl(rax, FieldOperand(rbx, FixedArray::kLengthOffset));
6957   __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
6958   __ cmpl(rdx, rax);
6959   __ j(greater, &runtime);
6960
6961   // ecx: RegExp data (FixedArray)
6962   // Check the representation and encoding of the subject string.
6963   Label seq_string, seq_two_byte_string, check_code;
6964   const int kStringRepresentationEncodingMask =
6965       kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
6966   __ movq(rax, Operand(rsp, kSubjectOffset));
6967   __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
6968   __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
6969   __ andb(rbx, Immediate(kStringRepresentationEncodingMask));
6970   // First check for sequential string.
6971   ASSERT_EQ(0, kStringTag);
6972   ASSERT_EQ(0, kSeqStringTag);
6973   __ testb(rbx, Immediate(kIsNotStringMask | kStringRepresentationMask));
6974   __ j(zero, &seq_string);
6975
6976   // Check for flat cons string.
6977   // A flat cons string is a cons string where the second part is the empty
6978   // string. In that case the subject string is just the first part of the cons
6979   // string. Also in this case the first part of the cons string is known to be
6980   // a sequential string or an external string.
6981   __ movl(rdx, rbx);
6982   __ andb(rdx, Immediate(kStringRepresentationMask));
6983   __ cmpb(rdx, Immediate(kConsStringTag));
6984   __ j(not_equal, &runtime);
6985   __ movq(rdx, FieldOperand(rax, ConsString::kSecondOffset));
6986   __ Cmp(rdx, Factory::empty_string());
6987   __ j(not_equal, &runtime);
6988   __ movq(rax, FieldOperand(rax, ConsString::kFirstOffset));
6989   __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
6990   __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
6991   ASSERT_EQ(0, kSeqStringTag);
6992   __ testb(rbx, Immediate(kStringRepresentationMask));
6993   __ j(not_zero, &runtime);
6994   __ andb(rbx, Immediate(kStringRepresentationEncodingMask));
6995
6996   __ bind(&seq_string);
6997   // rax: subject string (sequential either ascii to two byte)
6998   // rbx: suject string type & kStringRepresentationEncodingMask
6999   // rcx: RegExp data (FixedArray)
7000   // Check that the irregexp code has been generated for an ascii string. If
7001   // it has, the field contains a code object otherwise it contains the hole.
7002   __ cmpb(rbx, Immediate(kStringTag | kSeqStringTag | kTwoByteStringTag));
7003   __ j(equal, &seq_two_byte_string);
7004   if (FLAG_debug_code) {
7005     __ cmpb(rbx, Immediate(kStringTag | kSeqStringTag | kAsciiStringTag));
7006     __ Check(equal, "Expected sequential ascii string");
7007   }
7008   __ movq(r12, FieldOperand(rcx, JSRegExp::kDataAsciiCodeOffset));
7009   __ Set(rdi, 1);  // Type is ascii.
7010   __ jmp(&check_code);
7011
7012   __ bind(&seq_two_byte_string);
7013   // rax: subject string
7014   // rcx: RegExp data (FixedArray)
7015   __ movq(r12, FieldOperand(rcx, JSRegExp::kDataUC16CodeOffset));
7016   __ Set(rdi, 0);  // Type is two byte.
7017
7018   __ bind(&check_code);
7019   // Check that the irregexp code has been generated for the actual string
7020   // encoding. If it has, the field contains a code object otherwise it contains
7021   // the hole.
7022   __ CmpObjectType(r12, CODE_TYPE, kScratchRegister);
7023   __ j(not_equal, &runtime);
7024
7025   // rax: subject string
7026   // rdi: encoding of subject string (1 if ascii, 0 if two_byte);
7027   // r12: code
7028   // Load used arguments before starting to push arguments for call to native
7029   // RegExp code to avoid handling changing stack height.
7030   __ movq(rbx, Operand(rsp, kPreviousIndexOffset));
7031   __ SmiToInteger64(rbx, rbx);  // Previous index from smi.
7032
7033   // rax: subject string
7034   // rbx: previous index
7035   // rdi: encoding of subject string (1 if ascii 0 if two_byte);
7036   // r12: code
7037   // All checks done. Now push arguments for native regexp code.
7038   __ IncrementCounter(&Counters::regexp_entry_native, 1);
7039
7040   // rsi is caller save on Windows and used to pass parameter on Linux.
7041   __ push(rsi);
7042
7043   static const int kRegExpExecuteArguments = 7;
7044   __ PrepareCallCFunction(kRegExpExecuteArguments);
7045   int argument_slots_on_stack =
7046       masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
7047
7048   // Argument 7: Indicate that this is a direct call from JavaScript.
7049   __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
7050           Immediate(1));
7051
7052   // Argument 6: Start (high end) of backtracking stack memory area.
7053   __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
7054   __ movq(r9, Operand(kScratchRegister, 0));
7055   __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
7056   __ addq(r9, Operand(kScratchRegister, 0));
7057   // Argument 6 passed in r9 on Linux and on the stack on Windows.
7058 #ifdef _WIN64
7059   __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), r9);
7060 #endif
7061
7062   // Argument 5: static offsets vector buffer.
7063   __ movq(r8, ExternalReference::address_of_static_offsets_vector());
7064   // Argument 5 passed in r8 on Linux and on the stack on Windows.
7065 #ifdef _WIN64
7066   __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r8);
7067 #endif
7068
7069   // First four arguments are passed in registers on both Linux and Windows.
7070 #ifdef _WIN64
7071   Register arg4 = r9;
7072   Register arg3 = r8;
7073   Register arg2 = rdx;
7074   Register arg1 = rcx;
7075 #else
7076   Register arg4 = rcx;
7077   Register arg3 = rdx;
7078   Register arg2 = rsi;
7079   Register arg1 = rdi;
7080 #endif
7081
7082   // Keep track on aliasing between argX defined above and the registers used.
7083   // rax: subject string
7084   // rbx: previous index
7085   // rdi: encoding of subject string (1 if ascii 0 if two_byte);
7086   // r12: code
7087
7088   // Argument 4: End of string data
7089   // Argument 3: Start of string data
7090   Label setup_two_byte, setup_rest;
7091   __ testb(rdi, rdi);
7092   __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
7093   __ j(zero, &setup_two_byte);
7094   __ lea(arg4, FieldOperand(rax, rdi, times_1, SeqAsciiString::kHeaderSize));
7095   __ lea(arg3, FieldOperand(rax, rbx, times_1, SeqAsciiString::kHeaderSize));
7096   __ jmp(&setup_rest);
7097   __ bind(&setup_two_byte);
7098   __ lea(arg4, FieldOperand(rax, rdi, times_2, SeqTwoByteString::kHeaderSize));
7099   __ lea(arg3, FieldOperand(rax, rbx, times_2, SeqTwoByteString::kHeaderSize));
7100
7101   __ bind(&setup_rest);
7102   // Argument 2: Previous index.
7103   __ movq(arg2, rbx);
7104
7105   // Argument 1: Subject string.
7106   __ movq(arg1, rax);
7107
7108   // Locate the code entry and call it.
7109   __ addq(r12, Immediate(Code::kHeaderSize - kHeapObjectTag));
7110   __ CallCFunction(r12, kRegExpExecuteArguments);
7111
7112   // rsi is caller save, as it is used to pass parameter.
7113   __ pop(rsi);
7114
7115   // Check the result.
7116   Label success;
7117   __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::SUCCESS));
7118   __ j(equal, &success);
7119   Label failure;
7120   __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::FAILURE));
7121   __ j(equal, &failure);
7122   __ cmpq(rax, Immediate(NativeRegExpMacroAssembler::EXCEPTION));
7123   // If not exception it can only be retry. Handle that in the runtime system.
7124   __ j(not_equal, &runtime);
7125   // Result must now be exception. If there is no pending exception already a
7126   // stack overflow (on the backtrack stack) was detected in RegExp code but
7127   // haven't created the exception yet. Handle that in the runtime system.
7128   // TODO(592) Rerunning the RegExp to get the stack overflow exception.
7129   ExternalReference pending_exception_address(Top::k_pending_exception_address);
7130   __ movq(kScratchRegister, pending_exception_address);
7131   __ Cmp(kScratchRegister, Factory::the_hole_value());
7132   __ j(equal, &runtime);
7133   __ bind(&failure);
7134   // For failure and exception return null.
7135   __ Move(rax, Factory::null_value());
7136   __ ret(4 * kPointerSize);
7137
7138   // Load RegExp data.
7139   __ bind(&success);
7140   __ movq(rax, Operand(rsp, kJSRegExpOffset));
7141   __ movq(rcx, FieldOperand(rax, JSRegExp::kDataOffset));
7142   __ movq(rdx, FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset));
7143   // Calculate number of capture registers (number_of_captures + 1) * 2.
7144   __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rdx, 1);
7145   __ addq(rdx, Immediate(2));  // rdx was number_of_captures * 2.
7146
7147   // rdx: Number of capture registers
7148   // Load last_match_info which is still known to be a fast case JSArray.
7149   __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
7150   __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset));
7151
7152   // rbx: last_match_info backing store (FixedArray)
7153   // rdx: number of capture registers
7154   // Store the capture count.
7155   __ Integer32ToSmi(kScratchRegister, rdx);
7156   __ movq(FieldOperand(rbx, RegExpImpl::kLastCaptureCountOffset),
7157           kScratchRegister);
7158   // Store last subject and last input.
7159   __ movq(rax, Operand(rsp, kSubjectOffset));
7160   __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax);
7161   __ movq(rcx, rbx);
7162   __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi);
7163   __ movq(rax, Operand(rsp, kSubjectOffset));
7164   __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax);
7165   __ movq(rcx, rbx);
7166   __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi);
7167
7168   // Get the static offsets vector filled by the native regexp code.
7169   __ movq(rcx, ExternalReference::address_of_static_offsets_vector());
7170
7171   // rbx: last_match_info backing store (FixedArray)
7172   // rcx: offsets vector
7173   // rdx: number of capture registers
7174   Label next_capture, done;
7175   __ movq(rax, Operand(rsp, kPreviousIndexOffset));
7176   // Capture register counter starts from number of capture registers and
7177   // counts down until wraping after zero.
7178   __ bind(&next_capture);
7179   __ subq(rdx, Immediate(1));
7180   __ j(negative, &done);
7181   // Read the value from the static offsets vector buffer and make it a smi.
7182   __ movl(rdi, Operand(rcx, rdx, times_int_size, 0));
7183   __ Integer32ToSmi(rdi, rdi, &runtime);
7184   // Store the smi value in the last match info.
7185   __ movq(FieldOperand(rbx,
7186                        rdx,
7187                        times_pointer_size,
7188                        RegExpImpl::kFirstCaptureOffset),
7189                        rdi);
7190   __ jmp(&next_capture);
7191   __ bind(&done);
7192
7193   // Return last match info.
7194   __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
7195   __ ret(4 * kPointerSize);
7196
7197   // Do the runtime call to execute the regexp.
7198   __ bind(&runtime);
7199   __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
7200 #endif  // V8_NATIVE_REGEXP
7201 }
7202
7203
7204 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
7205                                                          Register object,
7206                                                          Register result,
7207                                                          Register scratch1,
7208                                                          Register scratch2,
7209                                                          bool object_is_smi,
7210                                                          Label* not_found) {
7211   // Currently only lookup for smis. Check for smi if object is not known to be
7212   // a smi.
7213   if (!object_is_smi) {
7214     __ JumpIfNotSmi(object, not_found);
7215   }
7216
7217   // Use of registers. Register result is used as a temporary.
7218   Register number_string_cache = result;
7219   Register mask = scratch1;
7220   Register scratch = scratch2;
7221
7222   // Load the number string cache.
7223   __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
7224
7225   // Make the hash mask from the length of the number string cache. It
7226   // contains two elements (number and string) for each cache entry.
7227   __ movl(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
7228   __ shrl(mask, Immediate(1));  // Divide length by two (length is not a smi).
7229   __ subl(mask, Immediate(1));  // Make mask.
7230
7231   // Calculate the entry in the number string cache. The hash value in the
7232   // number string cache for smis is just the smi value.
7233   __ movq(scratch, object);
7234   __ SmiToInteger32(scratch, scratch);
7235   __ andl(scratch, mask);
7236
7237   // Each entry in string cache consists of two pointer sized fields,
7238   // but times_twice_pointer_size (multiplication by 16) scale factor
7239   // is not supported by addrmode on x64 platform.
7240   // So we have to premultiply entry index before lookup
7241   __ shl(scratch, Immediate(kPointerSizeLog2 + 1));
7242   // Check if the entry is the smi we are looking for.
7243   __ cmpq(object,
7244           FieldOperand(number_string_cache,
7245                        scratch,
7246                        times_1,
7247                        FixedArray::kHeaderSize));
7248   __ j(not_equal, not_found);
7249
7250   // Get the result from the cache.
7251   __ movq(result,
7252           FieldOperand(number_string_cache,
7253                        scratch,
7254                        times_1,
7255                        FixedArray::kHeaderSize + kPointerSize));
7256   __ IncrementCounter(&Counters::number_to_string_native, 1);
7257 }
7258
7259
7260 void NumberToStringStub::Generate(MacroAssembler* masm) {
7261   Label runtime;
7262
7263   __ movq(rbx, Operand(rsp, kPointerSize));
7264
7265   // Generate code to lookup number in the number string cache.
7266   GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime);
7267   __ ret(1 * kPointerSize);
7268
7269   __ bind(&runtime);
7270   // Handle number to string in the runtime system if not found in the cache.
7271   __ TailCallRuntime(Runtime::kNumberToString, 1, 1);
7272 }
7273
7274
7275 void CompareStub::Generate(MacroAssembler* masm) {
7276   Label call_builtin, done;
7277
7278   // NOTICE! This code is only reached after a smi-fast-case check, so
7279   // it is certain that at least one operand isn't a smi.
7280
7281   if (cc_ == equal) {  // Both strict and non-strict.
7282     Label slow;  // Fallthrough label.
7283     // Equality is almost reflexive (everything but NaN), so start by testing
7284     // for "identity and not NaN".
7285     {
7286       Label not_identical;
7287       __ cmpq(rax, rdx);
7288       __ j(not_equal, &not_identical);
7289       // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
7290       // so we do the second best thing - test it ourselves.
7291
7292       if (never_nan_nan_) {
7293         __ xor_(rax, rax);
7294         __ ret(0);
7295       } else {
7296         Label return_equal;
7297         Label heap_number;
7298         // If it's not a heap number, then return equal.
7299         __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
7300                Factory::heap_number_map());
7301         __ j(equal, &heap_number);
7302         __ bind(&return_equal);
7303         __ xor_(rax, rax);
7304         __ ret(0);
7305
7306         __ bind(&heap_number);
7307         // It is a heap number, so return non-equal if it's NaN and equal if
7308         // it's not NaN.
7309         // The representation of NaN values has all exponent bits (52..62) set,
7310         // and not all mantissa bits (0..51) clear.
7311         // We only allow QNaNs, which have bit 51 set (which also rules out
7312         // the value being Infinity).
7313
7314         // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
7315         // all bits in the mask are set. We only need to check the word
7316         // that contains the exponent and high bit of the mantissa.
7317         ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
7318         __ movl(rdx, FieldOperand(rdx, HeapNumber::kExponentOffset));
7319         __ xorl(rax, rax);
7320         __ addl(rdx, rdx);  // Shift value and mask so mask applies to top bits.
7321         __ cmpl(rdx, Immediate(kQuietNaNHighBitsMask << 1));
7322         __ setcc(above_equal, rax);
7323         __ ret(0);
7324       }
7325
7326       __ bind(&not_identical);
7327     }
7328
7329     // If we're doing a strict equality comparison, we don't have to do
7330     // type conversion, so we generate code to do fast comparison for objects
7331     // and oddballs. Non-smi numbers and strings still go through the usual
7332     // slow-case code.
7333     if (strict_) {
7334       // If either is a Smi (we know that not both are), then they can only
7335       // be equal if the other is a HeapNumber. If so, use the slow case.
7336       {
7337         Label not_smis;
7338         __ SelectNonSmi(rbx, rax, rdx, &not_smis);
7339
7340         // Check if the non-smi operand is a heap number.
7341         __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
7342                Factory::heap_number_map());
7343         // If heap number, handle it in the slow case.
7344         __ j(equal, &slow);
7345         // Return non-equal.  ebx (the lower half of rbx) is not zero.
7346         __ movq(rax, rbx);
7347         __ ret(0);
7348
7349         __ bind(&not_smis);
7350       }
7351
7352       // If either operand is a JSObject or an oddball value, then they are not
7353       // equal since their pointers are different
7354       // There is no test for undetectability in strict equality.
7355
7356       // If the first object is a JS object, we have done pointer comparison.
7357       ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
7358       Label first_non_object;
7359       __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
7360       __ j(below, &first_non_object);
7361       // Return non-zero (eax (not rax) is not zero)
7362       Label return_not_equal;
7363       ASSERT(kHeapObjectTag != 0);
7364       __ bind(&return_not_equal);
7365       __ ret(0);
7366
7367       __ bind(&first_non_object);
7368       // Check for oddballs: true, false, null, undefined.
7369       __ CmpInstanceType(rcx, ODDBALL_TYPE);
7370       __ j(equal, &return_not_equal);
7371
7372       __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
7373       __ j(above_equal, &return_not_equal);
7374
7375       // Check for oddballs: true, false, null, undefined.
7376       __ CmpInstanceType(rcx, ODDBALL_TYPE);
7377       __ j(equal, &return_not_equal);
7378
7379       // Fall through to the general case.
7380     }
7381     __ bind(&slow);
7382   }
7383
7384   // Push arguments below the return address to prepare jump to builtin.
7385   __ pop(rcx);
7386   __ push(rax);
7387   __ push(rdx);
7388   __ push(rcx);
7389
7390   // Inlined floating point compare.
7391   // Call builtin if operands are not floating point or smi.
7392   Label check_for_symbols;
7393   // Push arguments on stack, for helper functions.
7394   FloatingPointHelper::CheckNumberOperands(masm, &check_for_symbols);
7395   FloatingPointHelper::LoadFloatOperands(masm, rax, rdx);
7396   __ FCmp();
7397
7398   // Jump to builtin for NaN.
7399   __ j(parity_even, &call_builtin);
7400
7401   // TODO(1243847): Use cmov below once CpuFeatures are properly hooked up.
7402   Label below_lbl, above_lbl;
7403   // use rdx, rax to convert unsigned to signed comparison
7404   __ j(below, &below_lbl);
7405   __ j(above, &above_lbl);
7406
7407   __ xor_(rax, rax);  // equal
7408   __ ret(2 * kPointerSize);
7409
7410   __ bind(&below_lbl);
7411   __ movq(rax, Immediate(-1));
7412   __ ret(2 * kPointerSize);
7413
7414   __ bind(&above_lbl);
7415   __ movq(rax, Immediate(1));
7416   __ ret(2 * kPointerSize);  // rax, rdx were pushed
7417
7418   // Fast negative check for symbol-to-symbol equality.
7419   __ bind(&check_for_symbols);
7420   Label check_for_strings;
7421   if (cc_ == equal) {
7422     BranchIfNonSymbol(masm, &check_for_strings, rax, kScratchRegister);
7423     BranchIfNonSymbol(masm, &check_for_strings, rdx, kScratchRegister);
7424
7425     // We've already checked for object identity, so if both operands
7426     // are symbols they aren't equal. Register eax (not rax) already holds a
7427     // non-zero value, which indicates not equal, so just return.
7428     __ ret(2 * kPointerSize);
7429   }
7430
7431   __ bind(&check_for_strings);
7432
7433   __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &call_builtin);
7434
7435   // Inline comparison of ascii strings.
7436   StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
7437                                                      rdx,
7438                                                      rax,
7439                                                      rcx,
7440                                                      rbx,
7441                                                      rdi,
7442                                                      r8);
7443
7444 #ifdef DEBUG
7445   __ Abort("Unexpected fall-through from string comparison");
7446 #endif
7447
7448   __ bind(&call_builtin);
7449   // must swap argument order
7450   __ pop(rcx);
7451   __ pop(rdx);
7452   __ pop(rax);
7453   __ push(rdx);
7454   __ push(rax);
7455
7456   // Figure out which native to call and setup the arguments.
7457   Builtins::JavaScript builtin;
7458   if (cc_ == equal) {
7459     builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
7460   } else {
7461     builtin = Builtins::COMPARE;
7462     int ncr;  // NaN compare result
7463     if (cc_ == less || cc_ == less_equal) {
7464       ncr = GREATER;
7465     } else {
7466       ASSERT(cc_ == greater || cc_ == greater_equal);  // remaining cases
7467       ncr = LESS;
7468     }
7469     __ Push(Smi::FromInt(ncr));
7470   }
7471
7472   // Restore return address on the stack.
7473   __ push(rcx);
7474
7475   // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
7476   // tagged as a small integer.
7477   __ InvokeBuiltin(builtin, JUMP_FUNCTION);
7478 }
7479
7480
7481 void CompareStub::BranchIfNonSymbol(MacroAssembler* masm,
7482                                     Label* label,
7483                                     Register object,
7484                                     Register scratch) {
7485   __ JumpIfSmi(object, label);
7486   __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset));
7487   __ movzxbq(scratch,
7488              FieldOperand(scratch, Map::kInstanceTypeOffset));
7489   // Ensure that no non-strings have the symbol bit set.
7490   ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
7491   ASSERT(kSymbolTag != 0);
7492   __ testb(scratch, Immediate(kIsSymbolMask));
7493   __ j(zero, label);
7494 }
7495
7496
7497 // Call the function just below TOS on the stack with the given
7498 // arguments. The receiver is the TOS.
7499 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
7500                                       CallFunctionFlags flags,
7501                                       int position) {
7502   // Push the arguments ("left-to-right") on the stack.
7503   int arg_count = args->length();
7504   for (int i = 0; i < arg_count; i++) {
7505     Load(args->at(i));
7506   }
7507
7508   // Record the position for debugging purposes.
7509   CodeForSourcePosition(position);
7510
7511   // Use the shared code stub to call the function.
7512   InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
7513   CallFunctionStub call_function(arg_count, in_loop, flags);
7514   Result answer = frame_->CallStub(&call_function, arg_count + 1);
7515   // Restore context and replace function on the stack with the
7516   // result of the stub invocation.
7517   frame_->RestoreContextRegister();
7518   frame_->SetElementAt(0, &answer);
7519 }
7520
7521
7522 void InstanceofStub::Generate(MacroAssembler* masm) {
7523   // Implements "value instanceof function" operator.
7524   // Expected input state:
7525   //   rsp[0] : return address
7526   //   rsp[1] : function pointer
7527   //   rsp[2] : value
7528
7529   // Get the object - go slow case if it's a smi.
7530   Label slow;
7531   __ movq(rax, Operand(rsp, 2 * kPointerSize));
7532   __ JumpIfSmi(rax, &slow);
7533
7534   // Check that the left hand is a JS object. Leave its map in rax.
7535   __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);
7536   __ j(below, &slow);
7537   __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE);
7538   __ j(above, &slow);
7539
7540   // Get the prototype of the function.
7541   __ movq(rdx, Operand(rsp, 1 * kPointerSize));
7542   __ TryGetFunctionPrototype(rdx, rbx, &slow);
7543
7544   // Check that the function prototype is a JS object.
7545   __ JumpIfSmi(rbx, &slow);
7546   __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister);
7547   __ j(below, &slow);
7548   __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
7549   __ j(above, &slow);
7550
7551   // Register mapping: rax is object map and rbx is function prototype.
7552   __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset));
7553
7554   // Loop through the prototype chain looking for the function prototype.
7555   Label loop, is_instance, is_not_instance;
7556   __ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex);
7557   __ bind(&loop);
7558   __ cmpq(rcx, rbx);
7559   __ j(equal, &is_instance);
7560   __ cmpq(rcx, kScratchRegister);
7561   __ j(equal, &is_not_instance);
7562   __ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
7563   __ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset));
7564   __ jmp(&loop);
7565
7566   __ bind(&is_instance);
7567   __ xorl(rax, rax);
7568   __ ret(2 * kPointerSize);
7569
7570   __ bind(&is_not_instance);
7571   __ movl(rax, Immediate(1));
7572   __ ret(2 * kPointerSize);
7573
7574   // Slow-case: Go through the JavaScript implementation.
7575   __ bind(&slow);
7576   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
7577 }
7578
7579
7580 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
7581   // rsp[0] : return address
7582   // rsp[8] : number of parameters
7583   // rsp[16] : receiver displacement
7584   // rsp[24] : function
7585
7586   // The displacement is used for skipping the return address and the
7587   // frame pointer on the stack. It is the offset of the last
7588   // parameter (if any) relative to the frame pointer.
7589   static const int kDisplacement = 2 * kPointerSize;
7590
7591   // Check if the calling frame is an arguments adaptor frame.
7592   Label adaptor_frame, try_allocate, runtime;
7593   __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
7594   __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
7595                 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
7596   __ j(equal, &adaptor_frame);
7597
7598   // Get the length from the frame.
7599   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
7600   __ jmp(&try_allocate);
7601
7602   // Patch the arguments.length and the parameters pointer.
7603   __ bind(&adaptor_frame);
7604   __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
7605   __ movq(Operand(rsp, 1 * kPointerSize), rcx);
7606   // Do not clobber the length index for the indexing operation since
7607   // it is used compute the size for allocation later.
7608   SmiIndex index = masm->SmiToIndex(rbx, rcx, kPointerSizeLog2);
7609   __ lea(rdx, Operand(rdx, index.reg, index.scale, kDisplacement));
7610   __ movq(Operand(rsp, 2 * kPointerSize), rdx);
7611
7612   // Try the new space allocation. Start out with computing the size of
7613   // the arguments object and the elements array.
7614   Label add_arguments_object;
7615   __ bind(&try_allocate);
7616   __ testq(rcx, rcx);
7617   __ j(zero, &add_arguments_object);
7618   index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2);
7619   __ lea(rcx, Operand(index.reg, index.scale, FixedArray::kHeaderSize));
7620   __ bind(&add_arguments_object);
7621   __ addq(rcx, Immediate(Heap::kArgumentsObjectSize));
7622
7623   // Do the allocation of both objects in one go.
7624   __ AllocateInNewSpace(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
7625
7626   // Get the arguments boilerplate from the current (global) context.
7627   int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
7628   __ movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
7629   __ movq(rdi, FieldOperand(rdi, GlobalObject::kGlobalContextOffset));
7630   __ movq(rdi, Operand(rdi, offset));
7631
7632   // Copy the JS object part.
7633   for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
7634     __ movq(kScratchRegister, FieldOperand(rdi, i));
7635     __ movq(FieldOperand(rax, i), kScratchRegister);
7636   }
7637
7638   // Setup the callee in-object property.
7639   ASSERT(Heap::arguments_callee_index == 0);
7640   __ movq(kScratchRegister, Operand(rsp, 3 * kPointerSize));
7641   __ movq(FieldOperand(rax, JSObject::kHeaderSize), kScratchRegister);
7642
7643   // Get the length (smi tagged) and set that as an in-object property too.
7644   ASSERT(Heap::arguments_length_index == 1);
7645   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
7646   __ movq(FieldOperand(rax, JSObject::kHeaderSize + kPointerSize), rcx);
7647
7648   // If there are no actual arguments, we're done.
7649   Label done;
7650   __ testq(rcx, rcx);
7651   __ j(zero, &done);
7652
7653   // Get the parameters pointer from the stack and untag the length.
7654   __ movq(rdx, Operand(rsp, 2 * kPointerSize));
7655   __ SmiToInteger32(rcx, rcx);
7656
7657   // Setup the elements pointer in the allocated arguments object and
7658   // initialize the header in the elements fixed array.
7659   __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
7660   __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
7661   __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
7662   __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
7663   __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
7664
7665   // Copy the fixed array slots.
7666   Label loop;
7667   __ bind(&loop);
7668   __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize));  // Skip receiver.
7669   __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister);
7670   __ addq(rdi, Immediate(kPointerSize));
7671   __ subq(rdx, Immediate(kPointerSize));
7672   __ decq(rcx);
7673   __ j(not_zero, &loop);
7674
7675   // Return and remove the on-stack parameters.
7676   __ bind(&done);
7677   __ ret(3 * kPointerSize);
7678
7679   // Do the runtime call to allocate the arguments object.
7680   __ bind(&runtime);
7681   __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
7682 }
7683
7684
7685 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
7686   // The key is in rdx and the parameter count is in rax.
7687
7688   // The displacement is used for skipping the frame pointer on the
7689   // stack. It is the offset of the last parameter (if any) relative
7690   // to the frame pointer.
7691   static const int kDisplacement = 1 * kPointerSize;
7692
7693   // Check that the key is a smi.
7694   Label slow;
7695   __ JumpIfNotSmi(rdx, &slow);
7696
7697   // Check if the calling frame is an arguments adaptor frame.
7698   Label adaptor;
7699   __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
7700   __ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset),
7701                 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
7702   __ j(equal, &adaptor);
7703
7704   // Check index against formal parameters count limit passed in
7705   // through register rax. Use unsigned comparison to get negative
7706   // check for free.
7707   __ cmpq(rdx, rax);
7708   __ j(above_equal, &slow);
7709
7710   // Read the argument from the stack and return it.
7711   SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
7712   __ lea(rbx, Operand(rbp, index.reg, index.scale, 0));
7713   index = masm->SmiToNegativeIndex(rdx, rdx, kPointerSizeLog2);
7714   __ movq(rax, Operand(rbx, index.reg, index.scale, kDisplacement));
7715   __ Ret();
7716
7717   // Arguments adaptor case: Check index against actual arguments
7718   // limit found in the arguments adaptor frame. Use unsigned
7719   // comparison to get negative check for free.
7720   __ bind(&adaptor);
7721   __ movq(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
7722   __ cmpq(rdx, rcx);
7723   __ j(above_equal, &slow);
7724
7725   // Read the argument from the stack and return it.
7726   index = masm->SmiToIndex(rax, rcx, kPointerSizeLog2);
7727   __ lea(rbx, Operand(rbx, index.reg, index.scale, 0));
7728   index = masm->SmiToNegativeIndex(rdx, rdx, kPointerSizeLog2);
7729   __ movq(rax, Operand(rbx, index.reg, index.scale, kDisplacement));
7730   __ Ret();
7731
7732   // Slow-case: Handle non-smi or out-of-bounds access to arguments
7733   // by calling the runtime system.
7734   __ bind(&slow);
7735   __ pop(rbx);  // Return address.
7736   __ push(rdx);
7737   __ push(rbx);
7738   __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
7739 }
7740
7741
7742 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
7743   // Check if the calling frame is an arguments adaptor frame.
7744   Label adaptor;
7745   __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
7746   __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset),
7747                 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
7748
7749   // Arguments adaptor case: Read the arguments length from the
7750   // adaptor frame and return it.
7751   // Otherwise nothing to do: The number of formal parameters has already been
7752   // passed in register eax by calling function. Just return it.
7753   __ cmovq(equal, rax,
7754            Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
7755   __ ret(0);
7756 }
7757
7758
7759 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
7760   // Check that stack should contain next handler, frame pointer, state and
7761   // return address in that order.
7762   ASSERT_EQ(StackHandlerConstants::kFPOffset + kPointerSize,
7763             StackHandlerConstants::kStateOffset);
7764   ASSERT_EQ(StackHandlerConstants::kStateOffset + kPointerSize,
7765             StackHandlerConstants::kPCOffset);
7766
7767   ExternalReference handler_address(Top::k_handler_address);
7768   __ movq(kScratchRegister, handler_address);
7769   __ movq(rsp, Operand(kScratchRegister, 0));
7770   // get next in chain
7771   __ pop(rcx);
7772   __ movq(Operand(kScratchRegister, 0), rcx);
7773   __ pop(rbp);  // pop frame pointer
7774   __ pop(rdx);  // remove state
7775
7776   // Before returning we restore the context from the frame pointer if not NULL.
7777   // The frame pointer is NULL in the exception handler of a JS entry frame.
7778   __ xor_(rsi, rsi);  // tentatively set context pointer to NULL
7779   Label skip;
7780   __ cmpq(rbp, Immediate(0));
7781   __ j(equal, &skip);
7782   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
7783   __ bind(&skip);
7784   __ ret(0);
7785 }
7786
7787
7788 void CEntryStub::GenerateCore(MacroAssembler* masm,
7789                               Label* throw_normal_exception,
7790                               Label* throw_termination_exception,
7791                               Label* throw_out_of_memory_exception,
7792                               bool do_gc,
7793                               bool always_allocate_scope) {
7794   // rax: result parameter for PerformGC, if any.
7795   // rbx: pointer to C function  (C callee-saved).
7796   // rbp: frame pointer  (restored after C call).
7797   // rsp: stack pointer  (restored after C call).
7798   // r14: number of arguments including receiver (C callee-saved).
7799   // r15: pointer to the first argument (C callee-saved).
7800   //      This pointer is reused in LeaveExitFrame(), so it is stored in a
7801   //      callee-saved register.
7802
7803   // Simple results returned in rax (both AMD64 and Win64 calling conventions).
7804   // Complex results must be written to address passed as first argument.
7805   // AMD64 calling convention: a struct of two pointers in rax+rdx
7806
7807   if (do_gc) {
7808     // Pass failure code returned from last attempt as first argument to GC.
7809 #ifdef _WIN64
7810     __ movq(rcx, rax);
7811 #else  // ! defined(_WIN64)
7812     __ movq(rdi, rax);
7813 #endif
7814     __ movq(kScratchRegister,
7815             FUNCTION_ADDR(Runtime::PerformGC),
7816             RelocInfo::RUNTIME_ENTRY);
7817     __ call(kScratchRegister);
7818   }
7819
7820   ExternalReference scope_depth =
7821       ExternalReference::heap_always_allocate_scope_depth();
7822   if (always_allocate_scope) {
7823     __ movq(kScratchRegister, scope_depth);
7824     __ incl(Operand(kScratchRegister, 0));
7825   }
7826
7827   // Call C function.
7828 #ifdef _WIN64
7829   // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9
7830   // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
7831   __ movq(Operand(rsp, 4 * kPointerSize), r14);  // argc.
7832   __ movq(Operand(rsp, 5 * kPointerSize), r15);  // argv.
7833   if (result_size_ < 2) {
7834     // Pass a pointer to the Arguments object as the first argument.
7835     // Return result in single register (rax).
7836     __ lea(rcx, Operand(rsp, 4 * kPointerSize));
7837   } else {
7838     ASSERT_EQ(2, result_size_);
7839     // Pass a pointer to the result location as the first argument.
7840     __ lea(rcx, Operand(rsp, 6 * kPointerSize));
7841     // Pass a pointer to the Arguments object as the second argument.
7842     __ lea(rdx, Operand(rsp, 4 * kPointerSize));
7843   }
7844
7845 #else  // ! defined(_WIN64)
7846   // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
7847   __ movq(rdi, r14);  // argc.
7848   __ movq(rsi, r15);  // argv.
7849 #endif
7850   __ call(rbx);
7851   // Result is in rax - do not destroy this register!
7852
7853   if (always_allocate_scope) {
7854     __ movq(kScratchRegister, scope_depth);
7855     __ decl(Operand(kScratchRegister, 0));
7856   }
7857
7858   // Check for failure result.
7859   Label failure_returned;
7860   ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
7861 #ifdef _WIN64
7862   // If return value is on the stack, pop it to registers.
7863   if (result_size_ > 1) {
7864     ASSERT_EQ(2, result_size_);
7865     // Read result values stored on stack. Result is stored
7866     // above the four argument mirror slots and the two
7867     // Arguments object slots.
7868     __ movq(rax, Operand(rsp, 6 * kPointerSize));
7869     __ movq(rdx, Operand(rsp, 7 * kPointerSize));
7870   }
7871 #endif
7872   __ lea(rcx, Operand(rax, 1));
7873   // Lower 2 bits of rcx are 0 iff rax has failure tag.
7874   __ testl(rcx, Immediate(kFailureTagMask));
7875   __ j(zero, &failure_returned);
7876
7877   // Exit the JavaScript to C++ exit frame.
7878   __ LeaveExitFrame(mode_, result_size_);
7879   __ ret(0);
7880
7881   // Handling of failure.
7882   __ bind(&failure_returned);
7883
7884   Label retry;
7885   // If the returned exception is RETRY_AFTER_GC continue at retry label
7886   ASSERT(Failure::RETRY_AFTER_GC == 0);
7887   __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
7888   __ j(zero, &retry);
7889
7890   // Special handling of out of memory exceptions.
7891   __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE);
7892   __ cmpq(rax, kScratchRegister);
7893   __ j(equal, throw_out_of_memory_exception);
7894
7895   // Retrieve the pending exception and clear the variable.
7896   ExternalReference pending_exception_address(Top::k_pending_exception_address);
7897   __ movq(kScratchRegister, pending_exception_address);
7898   __ movq(rax, Operand(kScratchRegister, 0));
7899   __ movq(rdx, ExternalReference::the_hole_value_location());
7900   __ movq(rdx, Operand(rdx, 0));
7901   __ movq(Operand(kScratchRegister, 0), rdx);
7902
7903   // Special handling of termination exceptions which are uncatchable
7904   // by javascript code.
7905   __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
7906   __ j(equal, throw_termination_exception);
7907
7908   // Handle normal exception.
7909   __ jmp(throw_normal_exception);
7910
7911   // Retry.
7912   __ bind(&retry);
7913 }
7914
7915
7916 void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm,
7917                                           UncatchableExceptionType type) {
7918   // Fetch top stack handler.
7919   ExternalReference handler_address(Top::k_handler_address);
7920   __ movq(kScratchRegister, handler_address);
7921   __ movq(rsp, Operand(kScratchRegister, 0));
7922
7923   // Unwind the handlers until the ENTRY handler is found.
7924   Label loop, done;
7925   __ bind(&loop);
7926   // Load the type of the current stack handler.
7927   const int kStateOffset = StackHandlerConstants::kStateOffset;
7928   __ cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY));
7929   __ j(equal, &done);
7930   // Fetch the next handler in the list.
7931   const int kNextOffset = StackHandlerConstants::kNextOffset;
7932   __ movq(rsp, Operand(rsp, kNextOffset));
7933   __ jmp(&loop);
7934   __ bind(&done);
7935
7936   // Set the top handler address to next handler past the current ENTRY handler.
7937   __ movq(kScratchRegister, handler_address);
7938   __ pop(Operand(kScratchRegister, 0));
7939
7940   if (type == OUT_OF_MEMORY) {
7941     // Set external caught exception to false.
7942     ExternalReference external_caught(Top::k_external_caught_exception_address);
7943     __ movq(rax, Immediate(false));
7944     __ store_rax(external_caught);
7945
7946     // Set pending exception and rax to out of memory exception.
7947     ExternalReference pending_exception(Top::k_pending_exception_address);
7948     __ movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
7949     __ store_rax(pending_exception);
7950   }
7951
7952   // Clear the context pointer.
7953   __ xor_(rsi, rsi);
7954
7955   // Restore registers from handler.
7956   ASSERT_EQ(StackHandlerConstants::kNextOffset + kPointerSize,
7957             StackHandlerConstants::kFPOffset);
7958   __ pop(rbp);  // FP
7959   ASSERT_EQ(StackHandlerConstants::kFPOffset + kPointerSize,
7960             StackHandlerConstants::kStateOffset);
7961   __ pop(rdx);  // State
7962
7963   ASSERT_EQ(StackHandlerConstants::kStateOffset + kPointerSize,
7964             StackHandlerConstants::kPCOffset);
7965   __ ret(0);
7966 }
7967
7968
7969 void CallFunctionStub::Generate(MacroAssembler* masm) {
7970   Label slow;
7971
7972   // If the receiver might be a value (string, number or boolean) check for this
7973   // and box it if it is.
7974   if (ReceiverMightBeValue()) {
7975     // Get the receiver from the stack.
7976     // +1 ~ return address
7977     Label receiver_is_value, receiver_is_js_object;
7978     __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
7979
7980     // Check if receiver is a smi (which is a number value).
7981     __ JumpIfSmi(rax, &receiver_is_value);
7982
7983     // Check if the receiver is a valid JS object.
7984     __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdi);
7985     __ j(above_equal, &receiver_is_js_object);
7986
7987     // Call the runtime to box the value.
7988     __ bind(&receiver_is_value);
7989     __ EnterInternalFrame();
7990     __ push(rax);
7991     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
7992     __ LeaveInternalFrame();
7993     __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rax);
7994
7995     __ bind(&receiver_is_js_object);
7996   }
7997
7998   // Get the function to call from the stack.
7999   // +2 ~ receiver, return address
8000   __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize));
8001
8002   // Check that the function really is a JavaScript function.
8003   __ JumpIfSmi(rdi, &slow);
8004   // Goto slow case if we do not have a function.
8005   __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
8006   __ j(not_equal, &slow);
8007
8008   // Fast-case: Just invoke the function.
8009   ParameterCount actual(argc_);
8010   __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
8011
8012   // Slow-case: Non-function called.
8013   __ bind(&slow);
8014   // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
8015   // of the original receiver from the call site).
8016   __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
8017   __ Set(rax, argc_);
8018   __ Set(rbx, 0);
8019   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
8020   Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
8021   __ Jump(adaptor, RelocInfo::CODE_TARGET);
8022 }
8023
8024
8025 void CEntryStub::Generate(MacroAssembler* masm) {
8026   // rax: number of arguments including receiver
8027   // rbx: pointer to C function  (C callee-saved)
8028   // rbp: frame pointer of calling JS frame (restored after C call)
8029   // rsp: stack pointer  (restored after C call)
8030   // rsi: current context (restored)
8031
8032   // NOTE: Invocations of builtins may return failure objects
8033   // instead of a proper result. The builtin entry handles
8034   // this by performing a garbage collection and retrying the
8035   // builtin once.
8036
8037   // Enter the exit frame that transitions from JavaScript to C++.
8038   __ EnterExitFrame(mode_, result_size_);
8039
8040   // rax: Holds the context at this point, but should not be used.
8041   //      On entry to code generated by GenerateCore, it must hold
8042   //      a failure result if the collect_garbage argument to GenerateCore
8043   //      is true.  This failure result can be the result of code
8044   //      generated by a previous call to GenerateCore.  The value
8045   //      of rax is then passed to Runtime::PerformGC.
8046   // rbx: pointer to builtin function  (C callee-saved).
8047   // rbp: frame pointer of exit frame  (restored after C call).
8048   // rsp: stack pointer (restored after C call).
8049   // r14: number of arguments including receiver (C callee-saved).
8050   // r15: argv pointer (C callee-saved).
8051
8052   Label throw_normal_exception;
8053   Label throw_termination_exception;
8054   Label throw_out_of_memory_exception;
8055
8056   // Call into the runtime system.
8057   GenerateCore(masm,
8058                &throw_normal_exception,
8059                &throw_termination_exception,
8060                &throw_out_of_memory_exception,
8061                false,
8062                false);
8063
8064   // Do space-specific GC and retry runtime call.
8065   GenerateCore(masm,
8066                &throw_normal_exception,
8067                &throw_termination_exception,
8068                &throw_out_of_memory_exception,
8069                true,
8070                false);
8071
8072   // Do full GC and retry runtime call one final time.
8073   Failure* failure = Failure::InternalError();
8074   __ movq(rax, failure, RelocInfo::NONE);
8075   GenerateCore(masm,
8076                &throw_normal_exception,
8077                &throw_termination_exception,
8078                &throw_out_of_memory_exception,
8079                true,
8080                true);
8081
8082   __ bind(&throw_out_of_memory_exception);
8083   GenerateThrowUncatchable(masm, OUT_OF_MEMORY);
8084
8085   __ bind(&throw_termination_exception);
8086   GenerateThrowUncatchable(masm, TERMINATION);
8087
8088   __ bind(&throw_normal_exception);
8089   GenerateThrowTOS(masm);
8090 }
8091
8092
8093 void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
8094   UNREACHABLE();
8095 }
8096
8097
8098 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
8099   Label invoke, exit;
8100 #ifdef ENABLE_LOGGING_AND_PROFILING
8101   Label not_outermost_js, not_outermost_js_2;
8102 #endif
8103
8104   // Setup frame.
8105   __ push(rbp);
8106   __ movq(rbp, rsp);
8107
8108   // Push the stack frame type marker twice.
8109   int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
8110   __ Push(Smi::FromInt(marker));  // context slot
8111   __ Push(Smi::FromInt(marker));  // function slot
8112   // Save callee-saved registers (X64 calling conventions).
8113   __ push(r12);
8114   __ push(r13);
8115   __ push(r14);
8116   __ push(r15);
8117   __ push(rdi);
8118   __ push(rsi);
8119   __ push(rbx);
8120   // TODO(X64): Push XMM6-XMM15 (low 64 bits) as well, or make them
8121   // callee-save in JS code as well.
8122
8123   // Save copies of the top frame descriptor on the stack.
8124   ExternalReference c_entry_fp(Top::k_c_entry_fp_address);
8125   __ load_rax(c_entry_fp);
8126   __ push(rax);
8127
8128 #ifdef ENABLE_LOGGING_AND_PROFILING
8129   // If this is the outermost JS call, set js_entry_sp value.
8130   ExternalReference js_entry_sp(Top::k_js_entry_sp_address);
8131   __ load_rax(js_entry_sp);
8132   __ testq(rax, rax);
8133   __ j(not_zero, &not_outermost_js);
8134   __ movq(rax, rbp);
8135   __ store_rax(js_entry_sp);
8136   __ bind(&not_outermost_js);
8137 #endif
8138
8139   // Call a faked try-block that does the invoke.
8140   __ call(&invoke);
8141
8142   // Caught exception: Store result (exception) in the pending
8143   // exception field in the JSEnv and return a failure sentinel.
8144   ExternalReference pending_exception(Top::k_pending_exception_address);
8145   __ store_rax(pending_exception);
8146   __ movq(rax, Failure::Exception(), RelocInfo::NONE);
8147   __ jmp(&exit);
8148
8149   // Invoke: Link this frame into the handler chain.
8150   __ bind(&invoke);
8151   __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
8152
8153   // Clear any pending exceptions.
8154   __ load_rax(ExternalReference::the_hole_value_location());
8155   __ store_rax(pending_exception);
8156
8157   // Fake a receiver (NULL).
8158   __ push(Immediate(0));  // receiver
8159
8160   // Invoke the function by calling through JS entry trampoline
8161   // builtin and pop the faked function when we return. We load the address
8162   // from an external reference instead of inlining the call target address
8163   // directly in the code, because the builtin stubs may not have been
8164   // generated yet at the time this code is generated.
8165   if (is_construct) {
8166     ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline);
8167     __ load_rax(construct_entry);
8168   } else {
8169     ExternalReference entry(Builtins::JSEntryTrampoline);
8170     __ load_rax(entry);
8171   }
8172   __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
8173   __ call(kScratchRegister);
8174
8175   // Unlink this frame from the handler chain.
8176   __ movq(kScratchRegister, ExternalReference(Top::k_handler_address));
8177   __ pop(Operand(kScratchRegister, 0));
8178   // Pop next_sp.
8179   __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
8180
8181 #ifdef ENABLE_LOGGING_AND_PROFILING
8182   // If current EBP value is the same as js_entry_sp value, it means that
8183   // the current function is the outermost.
8184   __ movq(kScratchRegister, js_entry_sp);
8185   __ cmpq(rbp, Operand(kScratchRegister, 0));
8186   __ j(not_equal, &not_outermost_js_2);
8187   __ movq(Operand(kScratchRegister, 0), Immediate(0));
8188   __ bind(&not_outermost_js_2);
8189 #endif
8190
8191   // Restore the top frame descriptor from the stack.
8192   __ bind(&exit);
8193   __ movq(kScratchRegister, ExternalReference(Top::k_c_entry_fp_address));
8194   __ pop(Operand(kScratchRegister, 0));
8195
8196   // Restore callee-saved registers (X64 conventions).
8197   __ pop(rbx);
8198   __ pop(rsi);
8199   __ pop(rdi);
8200   __ pop(r15);
8201   __ pop(r14);
8202   __ pop(r13);
8203   __ pop(r12);
8204   __ addq(rsp, Immediate(2 * kPointerSize));  // remove markers
8205
8206   // Restore frame pointer and return.
8207   __ pop(rbp);
8208   __ ret(0);
8209 }
8210
8211
8212 // -----------------------------------------------------------------------------
8213 // Implementation of stubs.
8214
8215 //  Stub classes have public member named masm, not masm_.
8216
8217 void StackCheckStub::Generate(MacroAssembler* masm) {
8218   // Because builtins always remove the receiver from the stack, we
8219   // have to fake one to avoid underflowing the stack. The receiver
8220   // must be inserted below the return address on the stack so we
8221   // temporarily store that in a register.
8222   __ pop(rax);
8223   __ Push(Smi::FromInt(0));
8224   __ push(rax);
8225
8226   // Do tail-call to runtime routine.
8227   __ TailCallRuntime(Runtime::kStackGuard, 1, 1);
8228 }
8229
8230
8231 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
8232                                            Register number) {
8233   Label load_smi, done;
8234
8235   __ JumpIfSmi(number, &load_smi);
8236   __ fld_d(FieldOperand(number, HeapNumber::kValueOffset));
8237   __ jmp(&done);
8238
8239   __ bind(&load_smi);
8240   __ SmiToInteger32(number, number);
8241   __ push(number);
8242   __ fild_s(Operand(rsp, 0));
8243   __ pop(number);
8244
8245   __ bind(&done);
8246 }
8247
8248
8249 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
8250                                            Register src,
8251                                            XMMRegister dst) {
8252   Label load_smi, done;
8253
8254   __ JumpIfSmi(src, &load_smi);
8255   __ movsd(dst, FieldOperand(src, HeapNumber::kValueOffset));
8256   __ jmp(&done);
8257
8258   __ bind(&load_smi);
8259   __ SmiToInteger32(src, src);
8260   __ cvtlsi2sd(dst, src);
8261
8262   __ bind(&done);
8263 }
8264
8265
8266 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
8267                                             XMMRegister dst1,
8268                                             XMMRegister dst2) {
8269   __ movq(kScratchRegister, rdx);
8270   LoadFloatOperand(masm, kScratchRegister, dst1);
8271   __ movq(kScratchRegister, rax);
8272   LoadFloatOperand(masm, kScratchRegister, dst2);
8273 }
8274
8275
8276 void FloatingPointHelper::LoadFloatOperandsFromSmis(MacroAssembler* masm,
8277                                                     XMMRegister dst1,
8278                                                     XMMRegister dst2) {
8279   __ SmiToInteger32(kScratchRegister, rdx);
8280   __ cvtlsi2sd(dst1, kScratchRegister);
8281   __ SmiToInteger32(kScratchRegister, rax);
8282   __ cvtlsi2sd(dst2, kScratchRegister);
8283 }
8284
8285
8286 // Input: rdx, rax are the left and right objects of a bit op.
8287 // Output: rax, rcx are left and right integers for a bit op.
8288 void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
8289                                          bool use_sse3,
8290                                          Label* conversion_failure) {
8291   // Check float operands.
8292   Label arg1_is_object, check_undefined_arg1;
8293   Label arg2_is_object, check_undefined_arg2;
8294   Label load_arg2, done;
8295
8296   __ JumpIfNotSmi(rdx, &arg1_is_object);
8297   __ SmiToInteger32(rdx, rdx);
8298   __ jmp(&load_arg2);
8299
8300   // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
8301   __ bind(&check_undefined_arg1);
8302   __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
8303   __ j(not_equal, conversion_failure);
8304   __ movl(rdx, Immediate(0));
8305   __ jmp(&load_arg2);
8306
8307   __ bind(&arg1_is_object);
8308   __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
8309   __ CompareRoot(rbx, Heap::kHeapNumberMapRootIndex);
8310   __ j(not_equal, &check_undefined_arg1);
8311   // Get the untagged integer version of the edx heap number in rcx.
8312   IntegerConvert(masm, rdx, use_sse3, conversion_failure);
8313   __ movl(rdx, rcx);
8314
8315   // Here edx has the untagged integer, eax has a Smi or a heap number.
8316   __ bind(&load_arg2);
8317   // Test if arg2 is a Smi.
8318   __ JumpIfNotSmi(rax, &arg2_is_object);
8319   __ SmiToInteger32(rax, rax);
8320   __ movl(rcx, rax);
8321   __ jmp(&done);
8322
8323   // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
8324   __ bind(&check_undefined_arg2);
8325   __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
8326   __ j(not_equal, conversion_failure);
8327   __ movl(rcx, Immediate(0));
8328   __ jmp(&done);
8329
8330   __ bind(&arg2_is_object);
8331   __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
8332   __ CompareRoot(rbx, Heap::kHeapNumberMapRootIndex);
8333   __ j(not_equal, &check_undefined_arg2);
8334   // Get the untagged integer version of the eax heap number in ecx.
8335   IntegerConvert(masm, rax, use_sse3, conversion_failure);
8336   __ bind(&done);
8337   __ movl(rax, rdx);
8338 }
8339
8340
8341 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm,
8342                                             Register lhs,
8343                                             Register rhs) {
8344   Label load_smi_lhs, load_smi_rhs, done_load_lhs, done;
8345   __ JumpIfSmi(lhs, &load_smi_lhs);
8346   __ fld_d(FieldOperand(lhs, HeapNumber::kValueOffset));
8347   __ bind(&done_load_lhs);
8348
8349   __ JumpIfSmi(rhs, &load_smi_rhs);
8350   __ fld_d(FieldOperand(rhs, HeapNumber::kValueOffset));
8351   __ jmp(&done);
8352
8353   __ bind(&load_smi_lhs);
8354   __ SmiToInteger64(kScratchRegister, lhs);
8355   __ push(kScratchRegister);
8356   __ fild_d(Operand(rsp, 0));
8357   __ pop(kScratchRegister);
8358   __ jmp(&done_load_lhs);
8359
8360   __ bind(&load_smi_rhs);
8361   __ SmiToInteger64(kScratchRegister, rhs);
8362   __ push(kScratchRegister);
8363   __ fild_d(Operand(rsp, 0));
8364   __ pop(kScratchRegister);
8365
8366   __ bind(&done);
8367 }
8368
8369
8370 void FloatingPointHelper::CheckNumberOperands(MacroAssembler* masm,
8371                                               Label* non_float) {
8372   Label test_other, done;
8373   // Test if both operands are numbers (heap_numbers or smis).
8374   // If not, jump to label non_float.
8375   __ JumpIfSmi(rdx, &test_other);  // argument in rdx is OK
8376   __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), Factory::heap_number_map());
8377   __ j(not_equal, non_float);  // The argument in rdx is not a number.
8378
8379   __ bind(&test_other);
8380   __ JumpIfSmi(rax, &done);  // argument in rax is OK
8381   __ Cmp(FieldOperand(rax, HeapObject::kMapOffset), Factory::heap_number_map());
8382   __ j(not_equal, non_float);  // The argument in rax is not a number.
8383
8384   // Fall-through: Both operands are numbers.
8385   __ bind(&done);
8386 }
8387
8388
8389 const char* GenericBinaryOpStub::GetName() {
8390   if (name_ != NULL) return name_;
8391   const int len = 100;
8392   name_ = Bootstrapper::AllocateAutoDeletedArray(len);
8393   if (name_ == NULL) return "OOM";
8394   const char* op_name = Token::Name(op_);
8395   const char* overwrite_name;
8396   switch (mode_) {
8397     case NO_OVERWRITE: overwrite_name = "Alloc"; break;
8398     case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
8399     case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
8400     default: overwrite_name = "UnknownOverwrite"; break;
8401   }
8402
8403   OS::SNPrintF(Vector<char>(name_, len),
8404                "GenericBinaryOpStub_%s_%s%s_%s%s_%s%s_%s",
8405                op_name,
8406                overwrite_name,
8407                (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "",
8408                args_in_registers_ ? "RegArgs" : "StackArgs",
8409                args_reversed_ ? "_R" : "",
8410                use_sse3_ ? "SSE3" : "SSE2",
8411                static_operands_type_.ToString(),
8412                BinaryOpIC::GetName(runtime_operands_type_));
8413   return name_;
8414 }
8415
8416
8417 void GenericBinaryOpStub::GenerateCall(
8418     MacroAssembler* masm,
8419     Register left,
8420     Register right) {
8421   if (!ArgsInRegistersSupported()) {
8422     // Pass arguments on the stack.
8423     __ push(left);
8424     __ push(right);
8425   } else {
8426     // The calling convention with registers is left in rdx and right in rax.
8427     Register left_arg = rdx;
8428     Register right_arg = rax;
8429     if (!(left.is(left_arg) && right.is(right_arg))) {
8430       if (left.is(right_arg) && right.is(left_arg)) {
8431         if (IsOperationCommutative()) {
8432           SetArgsReversed();
8433         } else {
8434           __ xchg(left, right);
8435         }
8436       } else if (left.is(left_arg)) {
8437         __ movq(right_arg, right);
8438       } else if (right.is(right_arg)) {
8439         __ movq(left_arg, left);
8440       } else if (left.is(right_arg)) {
8441         if (IsOperationCommutative()) {
8442           __ movq(left_arg, right);
8443           SetArgsReversed();
8444         } else {
8445           // Order of moves important to avoid destroying left argument.
8446           __ movq(left_arg, left);
8447           __ movq(right_arg, right);
8448         }
8449       } else if (right.is(left_arg)) {
8450         if (IsOperationCommutative()) {
8451           __ movq(right_arg, left);
8452           SetArgsReversed();
8453         } else {
8454           // Order of moves important to avoid destroying right argument.
8455           __ movq(right_arg, right);
8456           __ movq(left_arg, left);
8457         }
8458       } else {
8459         // Order of moves is not important.
8460         __ movq(left_arg, left);
8461         __ movq(right_arg, right);
8462       }
8463     }
8464
8465     // Update flags to indicate that arguments are in registers.
8466     SetArgsInRegisters();
8467     __ IncrementCounter(&Counters::generic_binary_stub_calls_regs, 1);
8468   }
8469
8470   // Call the stub.
8471   __ CallStub(this);
8472 }
8473
8474
8475 void GenericBinaryOpStub::GenerateCall(
8476     MacroAssembler* masm,
8477     Register left,
8478     Smi* right) {
8479   if (!ArgsInRegistersSupported()) {
8480     // Pass arguments on the stack.
8481     __ push(left);
8482     __ Push(right);
8483   } else {
8484     // The calling convention with registers is left in rdx and right in rax.
8485     Register left_arg = rdx;
8486     Register right_arg = rax;
8487     if (left.is(left_arg)) {
8488       __ Move(right_arg, right);
8489     } else if (left.is(right_arg) && IsOperationCommutative()) {
8490       __ Move(left_arg, right);
8491       SetArgsReversed();
8492     } else {
8493       // For non-commutative operations, left and right_arg might be
8494       // the same register.  Therefore, the order of the moves is
8495       // important here in order to not overwrite left before moving
8496       // it to left_arg.
8497       __ movq(left_arg, left);
8498       __ Move(right_arg, right);
8499     }
8500
8501     // Update flags to indicate that arguments are in registers.
8502     SetArgsInRegisters();
8503     __ IncrementCounter(&Counters::generic_binary_stub_calls_regs, 1);
8504   }
8505
8506   // Call the stub.
8507   __ CallStub(this);
8508 }
8509
8510
8511 void GenericBinaryOpStub::GenerateCall(
8512     MacroAssembler* masm,
8513     Smi* left,
8514     Register right) {
8515   if (!ArgsInRegistersSupported()) {
8516     // Pass arguments on the stack.
8517     __ Push(left);
8518     __ push(right);
8519   } else {
8520     // The calling convention with registers is left in rdx and right in rax.
8521     Register left_arg = rdx;
8522     Register right_arg = rax;
8523     if (right.is(right_arg)) {
8524       __ Move(left_arg, left);
8525     } else if (right.is(left_arg) && IsOperationCommutative()) {
8526       __ Move(right_arg, left);
8527       SetArgsReversed();
8528     } else {
8529       // For non-commutative operations, right and left_arg might be
8530       // the same register.  Therefore, the order of the moves is
8531       // important here in order to not overwrite right before moving
8532       // it to right_arg.
8533       __ movq(right_arg, right);
8534       __ Move(left_arg, left);
8535     }
8536     // Update flags to indicate that arguments are in registers.
8537     SetArgsInRegisters();
8538     __ IncrementCounter(&Counters::generic_binary_stub_calls_regs, 1);
8539   }
8540
8541   // Call the stub.
8542   __ CallStub(this);
8543 }
8544
8545
8546 Result GenericBinaryOpStub::GenerateCall(MacroAssembler* masm,
8547                                          VirtualFrame* frame,
8548                                          Result* left,
8549                                          Result* right) {
8550   if (ArgsInRegistersSupported()) {
8551     SetArgsInRegisters();
8552     return frame->CallStub(this, left, right);
8553   } else {
8554     frame->Push(left);
8555     frame->Push(right);
8556     return frame->CallStub(this, 2);
8557   }
8558 }
8559
8560
8561 void GenericBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, Label* slow) {
8562   // 1. Move arguments into rdx, rax except for DIV and MOD, which need the
8563   // dividend in rax and rdx free for the division.  Use rax, rbx for those.
8564   Comment load_comment(masm, "-- Load arguments");
8565   Register left = rdx;
8566   Register right = rax;
8567   if (op_ == Token::DIV || op_ == Token::MOD) {
8568     left = rax;
8569     right = rbx;
8570     if (HasArgsInRegisters()) {
8571       __ movq(rbx, rax);
8572       __ movq(rax, rdx);
8573     }
8574   }
8575   if (!HasArgsInRegisters()) {
8576     __ movq(right, Operand(rsp, 1 * kPointerSize));
8577     __ movq(left, Operand(rsp, 2 * kPointerSize));
8578   }
8579
8580   // 2. Smi check both operands. Skip the check for OR as it is better combined
8581   // with the actual operation.
8582   Label not_smis;
8583   if (op_ != Token::BIT_OR) {
8584     Comment smi_check_comment(masm, "-- Smi check arguments");
8585     __ JumpIfNotBothSmi(left, right, &not_smis);
8586   }
8587
8588   // 3. Operands are both smis (except for OR), perform the operation leaving
8589   // the result in rax and check the result if necessary.
8590   Comment perform_smi(masm, "-- Perform smi operation");
8591   Label use_fp_on_smis;
8592   switch (op_) {
8593     case Token::ADD: {
8594       ASSERT(right.is(rax));
8595       __ SmiAdd(right, right, left, &use_fp_on_smis);  // ADD is commutative.
8596       break;
8597     }
8598
8599     case Token::SUB: {
8600       __ SmiSub(left, left, right, &use_fp_on_smis);
8601       __ movq(rax, left);
8602       break;
8603     }
8604
8605     case Token::MUL:
8606       ASSERT(right.is(rax));
8607       __ SmiMul(right, right, left, &use_fp_on_smis);  // MUL is commutative.
8608       break;
8609
8610     case Token::DIV:
8611       ASSERT(left.is(rax));
8612       __ SmiDiv(left, left, right, &use_fp_on_smis);
8613       break;
8614
8615     case Token::MOD:
8616       ASSERT(left.is(rax));
8617       __ SmiMod(left, left, right, slow);
8618       break;
8619
8620     case Token::BIT_OR:
8621       ASSERT(right.is(rax));
8622       __ movq(rcx, right);  // Save the right operand.
8623       __ SmiOr(right, right, left);  // BIT_OR is commutative.
8624       __ testb(right, Immediate(kSmiTagMask));
8625       __ j(not_zero, &not_smis);
8626       break;
8627
8628     case Token::BIT_AND:
8629       ASSERT(right.is(rax));
8630       __ SmiAnd(right, right, left);  // BIT_AND is commutative.
8631       break;
8632
8633     case Token::BIT_XOR:
8634       ASSERT(right.is(rax));
8635       __ SmiXor(right, right, left);  // BIT_XOR is commutative.
8636       break;
8637
8638     case Token::SHL:
8639     case Token::SHR:
8640     case Token::SAR:
8641       switch (op_) {
8642         case Token::SAR:
8643           __ SmiShiftArithmeticRight(left, left, right);
8644           break;
8645         case Token::SHR:
8646           __ SmiShiftLogicalRight(left, left, right, slow);
8647           break;
8648         case Token::SHL:
8649           __ SmiShiftLeft(left, left, right, slow);
8650           break;
8651         default:
8652           UNREACHABLE();
8653       }
8654       __ movq(rax, left);
8655       break;
8656
8657     default:
8658       UNREACHABLE();
8659       break;
8660   }
8661
8662   // 4. Emit return of result in rax.
8663   GenerateReturn(masm);
8664
8665   // 5. For some operations emit inline code to perform floating point
8666   // operations on known smis (e.g., if the result of the operation
8667   // overflowed the smi range).
8668   switch (op_) {
8669     case Token::ADD:
8670     case Token::SUB:
8671     case Token::MUL:
8672     case Token::DIV: {
8673       __ bind(&use_fp_on_smis);
8674       if (op_ == Token::DIV) {
8675         __ movq(rdx, rax);
8676         __ movq(rax, rbx);
8677       }
8678       // left is rdx, right is rax.
8679       __ AllocateHeapNumber(rbx, rcx, slow);
8680       FloatingPointHelper::LoadFloatOperandsFromSmis(masm, xmm4, xmm5);
8681       switch (op_) {
8682         case Token::ADD: __ addsd(xmm4, xmm5); break;
8683         case Token::SUB: __ subsd(xmm4, xmm5); break;
8684         case Token::MUL: __ mulsd(xmm4, xmm5); break;
8685         case Token::DIV: __ divsd(xmm4, xmm5); break;
8686         default: UNREACHABLE();
8687       }
8688       __ movsd(FieldOperand(rbx, HeapNumber::kValueOffset), xmm4);
8689       __ movq(rax, rbx);
8690       GenerateReturn(masm);
8691     }
8692     default:
8693       break;
8694   }
8695
8696   // 6. Non-smi operands, fall out to the non-smi code with the operands in
8697   // rdx and rax.
8698   Comment done_comment(masm, "-- Enter non-smi code");
8699   __ bind(&not_smis);
8700
8701   switch (op_) {
8702     case Token::DIV:
8703     case Token::MOD:
8704       // Operands are in rax, rbx at this point.
8705       __ movq(rdx, rax);
8706       __ movq(rax, rbx);
8707       break;
8708
8709     case Token::BIT_OR:
8710       // Right operand is saved in rcx and rax was destroyed by the smi
8711       // operation.
8712       __ movq(rax, rcx);
8713       break;
8714
8715     default:
8716       break;
8717   }
8718 }
8719
8720
8721 void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
8722   Label call_runtime;
8723
8724   if (ShouldGenerateSmiCode()) {
8725     GenerateSmiCode(masm, &call_runtime);
8726   } else if (op_ != Token::MOD) {
8727     if (!HasArgsInRegisters()) {
8728       GenerateLoadArguments(masm);
8729     }
8730   }
8731   // Floating point case.
8732   if (ShouldGenerateFPCode()) {
8733     switch (op_) {
8734       case Token::ADD:
8735       case Token::SUB:
8736       case Token::MUL:
8737       case Token::DIV: {
8738         if (runtime_operands_type_ == BinaryOpIC::DEFAULT &&
8739             HasSmiCodeInStub()) {
8740           // Execution reaches this point when the first non-smi argument occurs
8741           // (and only if smi code is generated). This is the right moment to
8742           // patch to HEAP_NUMBERS state. The transition is attempted only for
8743           // the four basic operations. The stub stays in the DEFAULT state
8744           // forever for all other operations (also if smi code is skipped).
8745           GenerateTypeTransition(masm);
8746         }
8747
8748         Label not_floats;
8749         // rax: y
8750         // rdx: x
8751       if (static_operands_type_.IsNumber()) {
8752         if (FLAG_debug_code) {
8753           // Assert at runtime that inputs are only numbers.
8754           __ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number.");
8755           __ AbortIfNotNumber(rax, "GenericBinaryOpStub operand not a number.");
8756         }
8757       } else {
8758         FloatingPointHelper::CheckNumberOperands(masm, &call_runtime);
8759       }
8760         // Fast-case: Both operands are numbers.
8761         // xmm4 and xmm5 are volatile XMM registers.
8762         FloatingPointHelper::LoadFloatOperands(masm, xmm4, xmm5);
8763
8764         switch (op_) {
8765           case Token::ADD: __ addsd(xmm4, xmm5); break;
8766           case Token::SUB: __ subsd(xmm4, xmm5); break;
8767           case Token::MUL: __ mulsd(xmm4, xmm5); break;
8768           case Token::DIV: __ divsd(xmm4, xmm5); break;
8769           default: UNREACHABLE();
8770         }
8771         // Allocate a heap number, if needed.
8772         Label skip_allocation;
8773         OverwriteMode mode = mode_;
8774         if (HasArgsReversed()) {
8775           if (mode == OVERWRITE_RIGHT) {
8776             mode = OVERWRITE_LEFT;
8777           } else if (mode == OVERWRITE_LEFT) {
8778             mode = OVERWRITE_RIGHT;
8779           }
8780         }
8781         switch (mode) {
8782           case OVERWRITE_LEFT:
8783             __ JumpIfNotSmi(rdx, &skip_allocation);
8784             __ AllocateHeapNumber(rbx, rcx, &call_runtime);
8785             __ movq(rdx, rbx);
8786             __ bind(&skip_allocation);
8787             __ movq(rax, rdx);
8788             break;
8789           case OVERWRITE_RIGHT:
8790             // If the argument in rax is already an object, we skip the
8791             // allocation of a heap number.
8792             __ JumpIfNotSmi(rax, &skip_allocation);
8793             // Fall through!
8794           case NO_OVERWRITE:
8795             // Allocate a heap number for the result. Keep rax and rdx intact
8796             // for the possible runtime call.
8797             __ AllocateHeapNumber(rbx, rcx, &call_runtime);
8798             __ movq(rax, rbx);
8799             __ bind(&skip_allocation);
8800             break;
8801           default: UNREACHABLE();
8802         }
8803         __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm4);
8804         GenerateReturn(masm);
8805         __ bind(&not_floats);
8806         if (runtime_operands_type_ == BinaryOpIC::DEFAULT &&
8807             !HasSmiCodeInStub()) {
8808             // Execution reaches this point when the first non-number argument
8809             // occurs (and only if smi code is skipped from the stub, otherwise
8810             // the patching has already been done earlier in this case branch).
8811             // A perfect moment to try patching to STRINGS for ADD operation.
8812             if (op_ == Token::ADD) {
8813               GenerateTypeTransition(masm);
8814             }
8815         }
8816         break;
8817       }
8818       case Token::MOD: {
8819         // For MOD we go directly to runtime in the non-smi case.
8820         break;
8821       }
8822       case Token::BIT_OR:
8823       case Token::BIT_AND:
8824       case Token::BIT_XOR:
8825       case Token::SAR:
8826       case Token::SHL:
8827       case Token::SHR: {
8828         Label skip_allocation, non_smi_result;
8829         FloatingPointHelper::LoadAsIntegers(masm, use_sse3_, &call_runtime);
8830         switch (op_) {
8831           case Token::BIT_OR:  __ orl(rax, rcx); break;
8832           case Token::BIT_AND: __ andl(rax, rcx); break;
8833           case Token::BIT_XOR: __ xorl(rax, rcx); break;
8834           case Token::SAR: __ sarl_cl(rax); break;
8835           case Token::SHL: __ shll_cl(rax); break;
8836           case Token::SHR: __ shrl_cl(rax); break;
8837           default: UNREACHABLE();
8838         }
8839         if (op_ == Token::SHR) {
8840           // Check if result is non-negative. This can only happen for a shift
8841           // by zero, which also doesn't update the sign flag.
8842           __ testl(rax, rax);
8843           __ j(negative, &non_smi_result);
8844         }
8845         __ JumpIfNotValidSmiValue(rax, &non_smi_result);
8846         // Tag smi result, if possible, and return.
8847         __ Integer32ToSmi(rax, rax);
8848         GenerateReturn(masm);
8849
8850         // All ops except SHR return a signed int32 that we load in
8851         // a HeapNumber.
8852         if (op_ != Token::SHR && non_smi_result.is_linked()) {
8853           __ bind(&non_smi_result);
8854           // Allocate a heap number if needed.
8855           __ movsxlq(rbx, rax);  // rbx: sign extended 32-bit result
8856           switch (mode_) {
8857             case OVERWRITE_LEFT:
8858             case OVERWRITE_RIGHT:
8859               // If the operand was an object, we skip the
8860               // allocation of a heap number.
8861               __ movq(rax, Operand(rsp, mode_ == OVERWRITE_RIGHT ?
8862                                    1 * kPointerSize : 2 * kPointerSize));
8863               __ JumpIfNotSmi(rax, &skip_allocation);
8864               // Fall through!
8865             case NO_OVERWRITE:
8866               __ AllocateHeapNumber(rax, rcx, &call_runtime);
8867               __ bind(&skip_allocation);
8868               break;
8869             default: UNREACHABLE();
8870           }
8871           // Store the result in the HeapNumber and return.
8872           __ movq(Operand(rsp, 1 * kPointerSize), rbx);
8873           __ fild_s(Operand(rsp, 1 * kPointerSize));
8874           __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
8875           GenerateReturn(masm);
8876         }
8877
8878         // SHR should return uint32 - go to runtime for non-smi/negative result.
8879         if (op_ == Token::SHR) {
8880           __ bind(&non_smi_result);
8881         }
8882         break;
8883       }
8884       default: UNREACHABLE(); break;
8885     }
8886   }
8887
8888   // If all else fails, use the runtime system to get the correct
8889   // result. If arguments was passed in registers now place them on the
8890   // stack in the correct order below the return address.
8891   __ bind(&call_runtime);
8892
8893   if (HasArgsInRegisters()) {
8894     GenerateRegisterArgsPush(masm);
8895   }
8896
8897   switch (op_) {
8898     case Token::ADD: {
8899       // Registers containing left and right operands respectively.
8900       Register lhs, rhs;
8901
8902       if (HasArgsReversed()) {
8903         lhs = rax;
8904         rhs = rdx;
8905       } else {
8906         lhs = rdx;
8907         rhs = rax;
8908       }
8909
8910       // Test for string arguments before calling runtime.
8911       Label not_strings, both_strings, not_string1, string1, string1_smi2;
8912
8913       // If this stub has already generated FP-specific code then the arguments
8914       // are already in rdx, rax
8915       if (!ShouldGenerateFPCode() && !HasArgsInRegisters()) {
8916         GenerateLoadArguments(masm);
8917       }
8918
8919       Condition is_smi;
8920       is_smi = masm->CheckSmi(lhs);
8921       __ j(is_smi, &not_string1);
8922       __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, r8);
8923       __ j(above_equal, &not_string1);
8924
8925       // First argument is a a string, test second.
8926       is_smi = masm->CheckSmi(rhs);
8927       __ j(is_smi, &string1_smi2);
8928       __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, r9);
8929       __ j(above_equal, &string1);
8930
8931       // First and second argument are strings.
8932       StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
8933       __ TailCallStub(&string_add_stub);
8934
8935       __ bind(&string1_smi2);
8936       // First argument is a string, second is a smi. Try to lookup the number
8937       // string for the smi in the number string cache.
8938       NumberToStringStub::GenerateLookupNumberStringCache(
8939           masm, rhs, rbx, rcx, r8, true, &string1);
8940
8941       // Replace second argument on stack and tailcall string add stub to make
8942       // the result.
8943       __ movq(Operand(rsp, 1 * kPointerSize), rbx);
8944       __ TailCallStub(&string_add_stub);
8945
8946       // Only first argument is a string.
8947       __ bind(&string1);
8948       __ InvokeBuiltin(Builtins::STRING_ADD_LEFT, JUMP_FUNCTION);
8949
8950       // First argument was not a string, test second.
8951       __ bind(&not_string1);
8952       is_smi = masm->CheckSmi(rhs);
8953       __ j(is_smi, &not_strings);
8954       __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, rhs);
8955       __ j(above_equal, &not_strings);
8956
8957       // Only second argument is a string.
8958       __ InvokeBuiltin(Builtins::STRING_ADD_RIGHT, JUMP_FUNCTION);
8959
8960       __ bind(&not_strings);
8961       // Neither argument is a string.
8962       __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
8963       break;
8964     }
8965     case Token::SUB:
8966       __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
8967       break;
8968     case Token::MUL:
8969       __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
8970       break;
8971     case Token::DIV:
8972       __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
8973       break;
8974     case Token::MOD:
8975       __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
8976       break;
8977     case Token::BIT_OR:
8978       __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
8979       break;
8980     case Token::BIT_AND:
8981       __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION);
8982       break;
8983     case Token::BIT_XOR:
8984       __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION);
8985       break;
8986     case Token::SAR:
8987       __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION);
8988       break;
8989     case Token::SHL:
8990       __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION);
8991       break;
8992     case Token::SHR:
8993       __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
8994       break;
8995     default:
8996       UNREACHABLE();
8997   }
8998
8999   // TODO(kaznacheev) Remove this (along with clearing) if it does not harm
9000   // performance.
9001   // Generate an unreachable reference to the DEFAULT stub so that it can be
9002   // found at the end of this stub when clearing ICs at GC.
9003   if (runtime_operands_type_ != BinaryOpIC::DEFAULT) {
9004     GenericBinaryOpStub uninit(MinorKey(), BinaryOpIC::DEFAULT);
9005     __ TailCallStub(&uninit);
9006   }
9007 }
9008
9009
9010 void GenericBinaryOpStub::GenerateLoadArguments(MacroAssembler* masm) {
9011   ASSERT(!HasArgsInRegisters());
9012   __ movq(rax, Operand(rsp, 1 * kPointerSize));
9013   __ movq(rdx, Operand(rsp, 2 * kPointerSize));
9014 }
9015
9016
9017 void GenericBinaryOpStub::GenerateReturn(MacroAssembler* masm) {
9018   // If arguments are not passed in registers remove them from the stack before
9019   // returning.
9020   if (!HasArgsInRegisters()) {
9021     __ ret(2 * kPointerSize);  // Remove both operands
9022   } else {
9023     __ ret(0);
9024   }
9025 }
9026
9027
9028 void GenericBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
9029   ASSERT(HasArgsInRegisters());
9030   __ pop(rcx);
9031   if (HasArgsReversed()) {
9032     __ push(rax);
9033     __ push(rdx);
9034   } else {
9035     __ push(rdx);
9036     __ push(rax);
9037   }
9038   __ push(rcx);
9039 }
9040
9041
9042 void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
9043   Label get_result;
9044
9045   // Keep a copy of operands on the stack and make sure they are also in
9046   // rdx, rax.
9047   if (HasArgsInRegisters()) {
9048     GenerateRegisterArgsPush(masm);
9049   } else {
9050     GenerateLoadArguments(masm);
9051   }
9052
9053   // Internal frame is necessary to handle exceptions properly.
9054   __ EnterInternalFrame();
9055
9056   // Push arguments on stack if the stub expects them there.
9057   if (!HasArgsInRegisters()) {
9058     __ push(rdx);
9059     __ push(rax);
9060   }
9061   // Call the stub proper to get the result in rax.
9062   __ call(&get_result);
9063   __ LeaveInternalFrame();
9064
9065   // Left and right arguments are already on stack.
9066   __ pop(rcx);
9067   // Push the operation result. The tail call to BinaryOp_Patch will
9068   // return it to the original caller..
9069   __ push(rax);
9070
9071   // Push this stub's key.
9072   __ movq(rax, Immediate(MinorKey()));
9073   __ Integer32ToSmi(rax, rax);
9074   __ push(rax);
9075
9076   // Although the operation and the type info are encoded into the key,
9077   // the encoding is opaque, so push them too.
9078   __ movq(rax, Immediate(op_));
9079   __ Integer32ToSmi(rax, rax);
9080   __ push(rax);
9081
9082   __ movq(rax, Immediate(runtime_operands_type_));
9083   __ Integer32ToSmi(rax, rax);
9084   __ push(rax);
9085
9086   __ push(rcx);
9087
9088   // Perform patching to an appropriate fast case and return the result.
9089   __ TailCallExternalReference(
9090       ExternalReference(IC_Utility(IC::kBinaryOp_Patch)),
9091       6,
9092       1);
9093
9094   // The entry point for the result calculation is assumed to be immediately
9095   // after this sequence.
9096   __ bind(&get_result);
9097 }
9098
9099
9100 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) {
9101   GenericBinaryOpStub stub(key, type_info);
9102   return stub.GetCode();
9103 }
9104
9105
9106 int CompareStub::MinorKey() {
9107   // Encode the three parameters in a unique 16 bit value. To avoid duplicate
9108   // stubs the never NaN NaN condition is only taken into account if the
9109   // condition is equals.
9110   ASSERT(static_cast<unsigned>(cc_) < (1 << 13));
9111   return ConditionField::encode(static_cast<unsigned>(cc_))
9112          | StrictField::encode(strict_)
9113          | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false)
9114          | IncludeNumberCompareField::encode(include_number_compare_);
9115 }
9116
9117
9118 // Unfortunately you have to run without snapshots to see most of these
9119 // names in the profile since most compare stubs end up in the snapshot.
9120 const char* CompareStub::GetName() {
9121   if (name_ != NULL) return name_;
9122   const int kMaxNameLength = 100;
9123   name_ = Bootstrapper::AllocateAutoDeletedArray(kMaxNameLength);
9124   if (name_ == NULL) return "OOM";
9125
9126   const char* cc_name;
9127   switch (cc_) {
9128     case less: cc_name = "LT"; break;
9129     case greater: cc_name = "GT"; break;
9130     case less_equal: cc_name = "LE"; break;
9131     case greater_equal: cc_name = "GE"; break;
9132     case equal: cc_name = "EQ"; break;
9133     case not_equal: cc_name = "NE"; break;
9134     default: cc_name = "UnknownCondition"; break;
9135   }
9136
9137   const char* strict_name = "";
9138   if (strict_ && (cc_ == equal || cc_ == not_equal)) {
9139     strict_name = "_STRICT";
9140   }
9141
9142   const char* never_nan_nan_name = "";
9143   if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
9144     never_nan_nan_name = "_NO_NAN";
9145   }
9146
9147   const char* include_number_compare_name = "";
9148   if (!include_number_compare_) {
9149     include_number_compare_name = "_NO_NUMBER";
9150   }
9151
9152   OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
9153                "CompareStub_%s%s%s%s",
9154                cc_name,
9155                strict_name,
9156                never_nan_nan_name,
9157                include_number_compare_name);
9158   return name_;
9159 }
9160
9161
9162 void StringAddStub::Generate(MacroAssembler* masm) {
9163   Label string_add_runtime;
9164
9165   // Load the two arguments.
9166   __ movq(rax, Operand(rsp, 2 * kPointerSize));  // First argument.
9167   __ movq(rdx, Operand(rsp, 1 * kPointerSize));  // Second argument.
9168
9169   // Make sure that both arguments are strings if not known in advance.
9170   if (string_check_) {
9171     Condition is_smi;
9172     is_smi = masm->CheckSmi(rax);
9173     __ j(is_smi, &string_add_runtime);
9174     __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, r8);
9175     __ j(above_equal, &string_add_runtime);
9176
9177     // First argument is a a string, test second.
9178     is_smi = masm->CheckSmi(rdx);
9179     __ j(is_smi, &string_add_runtime);
9180     __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, r9);
9181     __ j(above_equal, &string_add_runtime);
9182   }
9183
9184   // Both arguments are strings.
9185   // rax: first string
9186   // rdx: second string
9187   // Check if either of the strings are empty. In that case return the other.
9188   Label second_not_zero_length, both_not_zero_length;
9189   __ movl(rcx, FieldOperand(rdx, String::kLengthOffset));
9190   __ testl(rcx, rcx);
9191   __ j(not_zero, &second_not_zero_length);
9192   // Second string is empty, result is first string which is already in rax.
9193   __ IncrementCounter(&Counters::string_add_native, 1);
9194   __ ret(2 * kPointerSize);
9195   __ bind(&second_not_zero_length);
9196   __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
9197   __ testl(rbx, rbx);
9198   __ j(not_zero, &both_not_zero_length);
9199   // First string is empty, result is second string which is in rdx.
9200   __ movq(rax, rdx);
9201   __ IncrementCounter(&Counters::string_add_native, 1);
9202   __ ret(2 * kPointerSize);
9203
9204   // Both strings are non-empty.
9205   // rax: first string
9206   // rbx: length of first string
9207   // rcx: length of second string
9208   // rdx: second string
9209   // r8: map of first string if string check was performed above
9210   // r9: map of second string if string check was performed above
9211   Label string_add_flat_result, longer_than_two;
9212   __ bind(&both_not_zero_length);
9213
9214   // If arguments where known to be strings, maps are not loaded to r8 and r9
9215   // by the code above.
9216   if (!string_check_) {
9217     __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset));
9218     __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
9219   }
9220   // Get the instance types of the two strings as they will be needed soon.
9221   __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset));
9222   __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
9223
9224   // Look at the length of the result of adding the two strings.
9225   __ addl(rbx, rcx);
9226   // Use the runtime system when adding two one character strings, as it
9227   // contains optimizations for this specific case using the symbol table.
9228   __ cmpl(rbx, Immediate(2));
9229   __ j(not_equal, &longer_than_two);
9230
9231   // Check that both strings are non-external ascii strings.
9232   __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
9233                                                  &string_add_runtime);
9234
9235   // Get the two characters forming the sub string.
9236   __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize));
9237   __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize));
9238
9239   // Try to lookup two character string in symbol table. If it is not found
9240   // just allocate a new one.
9241   Label make_two_character_string, make_flat_ascii_string;
9242   GenerateTwoCharacterSymbolTableProbe(masm, rbx, rcx, r14, r12, rdi, r15,
9243                                        &make_two_character_string);
9244   __ IncrementCounter(&Counters::string_add_native, 1);
9245   __ ret(2 * kPointerSize);
9246
9247   __ bind(&make_two_character_string);
9248   __ Set(rbx, 2);
9249   __ jmp(&make_flat_ascii_string);
9250
9251   __ bind(&longer_than_two);
9252   // Check if resulting string will be flat.
9253   __ cmpl(rbx, Immediate(String::kMinNonFlatLength));
9254   __ j(below, &string_add_flat_result);
9255   // Handle exceptionally long strings in the runtime system.
9256   ASSERT((String::kMaxLength & 0x80000000) == 0);
9257   __ cmpl(rbx, Immediate(String::kMaxLength));
9258   __ j(above, &string_add_runtime);
9259
9260   // If result is not supposed to be flat, allocate a cons string object. If
9261   // both strings are ascii the result is an ascii cons string.
9262   // rax: first string
9263   // ebx: length of resulting flat string
9264   // rdx: second string
9265   // r8: instance type of first string
9266   // r9: instance type of second string
9267   Label non_ascii, allocated;
9268   __ movl(rcx, r8);
9269   __ and_(rcx, r9);
9270   ASSERT(kStringEncodingMask == kAsciiStringTag);
9271   __ testl(rcx, Immediate(kAsciiStringTag));
9272   __ j(zero, &non_ascii);
9273   // Allocate an acsii cons string.
9274   __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime);
9275   __ bind(&allocated);
9276   // Fill the fields of the cons string.
9277   __ movl(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
9278   __ movl(FieldOperand(rcx, ConsString::kHashFieldOffset),
9279           Immediate(String::kEmptyHashField));
9280   __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
9281   __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
9282   __ movq(rax, rcx);
9283   __ IncrementCounter(&Counters::string_add_native, 1);
9284   __ ret(2 * kPointerSize);
9285   __ bind(&non_ascii);
9286   // Allocate a two byte cons string.
9287   __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime);
9288   __ jmp(&allocated);
9289
9290   // Handle creating a flat result. First check that both strings are not
9291   // external strings.
9292   // rax: first string
9293   // ebx: length of resulting flat string
9294   // rdx: second string
9295   // r8: instance type of first string
9296   // r9: instance type of first string
9297   __ bind(&string_add_flat_result);
9298   __ movl(rcx, r8);
9299   __ and_(rcx, Immediate(kStringRepresentationMask));
9300   __ cmpl(rcx, Immediate(kExternalStringTag));
9301   __ j(equal, &string_add_runtime);
9302   __ movl(rcx, r9);
9303   __ and_(rcx, Immediate(kStringRepresentationMask));
9304   __ cmpl(rcx, Immediate(kExternalStringTag));
9305   __ j(equal, &string_add_runtime);
9306   // Now check if both strings are ascii strings.
9307   // rax: first string
9308   // ebx: length of resulting flat string
9309   // rdx: second string
9310   // r8: instance type of first string
9311   // r9: instance type of second string
9312   Label non_ascii_string_add_flat_result;
9313   ASSERT(kStringEncodingMask == kAsciiStringTag);
9314   __ testl(r8, Immediate(kAsciiStringTag));
9315   __ j(zero, &non_ascii_string_add_flat_result);
9316   __ testl(r9, Immediate(kAsciiStringTag));
9317   __ j(zero, &string_add_runtime);
9318
9319   __ bind(&make_flat_ascii_string);
9320   // Both strings are ascii strings. As they are short they are both flat.
9321   __ AllocateAsciiString(rcx, rbx, rdi, r14, r15, &string_add_runtime);
9322   // rcx: result string
9323   __ movq(rbx, rcx);
9324   // Locate first character of result.
9325   __ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9326   // Locate first character of first argument
9327   __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
9328   __ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9329   // rax: first char of first argument
9330   // rbx: result string
9331   // rcx: first character of result
9332   // rdx: second string
9333   // rdi: length of first argument
9334   GenerateCopyCharacters(masm, rcx, rax, rdi, true);
9335   // Locate first character of second argument.
9336   __ movl(rdi, FieldOperand(rdx, String::kLengthOffset));
9337   __ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9338   // rbx: result string
9339   // rcx: next character of result
9340   // rdx: first char of second argument
9341   // rdi: length of second argument
9342   GenerateCopyCharacters(masm, rcx, rdx, rdi, true);
9343   __ movq(rax, rbx);
9344   __ IncrementCounter(&Counters::string_add_native, 1);
9345   __ ret(2 * kPointerSize);
9346
9347   // Handle creating a flat two byte result.
9348   // rax: first string - known to be two byte
9349   // rbx: length of resulting flat string
9350   // rdx: second string
9351   // r8: instance type of first string
9352   // r9: instance type of first string
9353   __ bind(&non_ascii_string_add_flat_result);
9354   __ and_(r9, Immediate(kAsciiStringTag));
9355   __ j(not_zero, &string_add_runtime);
9356   // Both strings are two byte strings. As they are short they are both
9357   // flat.
9358   __ AllocateTwoByteString(rcx, rbx, rdi, r14, r15, &string_add_runtime);
9359   // rcx: result string
9360   __ movq(rbx, rcx);
9361   // Locate first character of result.
9362   __ addq(rcx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
9363   // Locate first character of first argument.
9364   __ movl(rdi, FieldOperand(rax, String::kLengthOffset));
9365   __ addq(rax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
9366   // rax: first char of first argument
9367   // rbx: result string
9368   // rcx: first character of result
9369   // rdx: second argument
9370   // rdi: length of first argument
9371   GenerateCopyCharacters(masm, rcx, rax, rdi, false);
9372   // Locate first character of second argument.
9373   __ movl(rdi, FieldOperand(rdx, String::kLengthOffset));
9374   __ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
9375   // rbx: result string
9376   // rcx: next character of result
9377   // rdx: first char of second argument
9378   // rdi: length of second argument
9379   GenerateCopyCharacters(masm, rcx, rdx, rdi, false);
9380   __ movq(rax, rbx);
9381   __ IncrementCounter(&Counters::string_add_native, 1);
9382   __ ret(2 * kPointerSize);
9383
9384   // Just jump to runtime to add the two strings.
9385   __ bind(&string_add_runtime);
9386   __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
9387 }
9388
9389
9390 void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
9391                                             Register dest,
9392                                             Register src,
9393                                             Register count,
9394                                             bool ascii) {
9395   Label loop;
9396   __ bind(&loop);
9397   // This loop just copies one character at a time, as it is only used for very
9398   // short strings.
9399   if (ascii) {
9400     __ movb(kScratchRegister, Operand(src, 0));
9401     __ movb(Operand(dest, 0), kScratchRegister);
9402     __ addq(src, Immediate(1));
9403     __ addq(dest, Immediate(1));
9404   } else {
9405     __ movzxwl(kScratchRegister, Operand(src, 0));
9406     __ movw(Operand(dest, 0), kScratchRegister);
9407     __ addq(src, Immediate(2));
9408     __ addq(dest, Immediate(2));
9409   }
9410   __ subl(count, Immediate(1));
9411   __ j(not_zero, &loop);
9412 }
9413
9414
9415 void StringStubBase::GenerateCopyCharactersREP(MacroAssembler* masm,
9416                                                Register dest,
9417                                                Register src,
9418                                                Register count,
9419                                                bool ascii) {
9420   // Copy characters using rep movs of doublewords. Align destination on 4 byte
9421   // boundary before starting rep movs. Copy remaining characters after running
9422   // rep movs.
9423   ASSERT(dest.is(rdi));  // rep movs destination
9424   ASSERT(src.is(rsi));  // rep movs source
9425   ASSERT(count.is(rcx));  // rep movs count
9426
9427   // Nothing to do for zero characters.
9428   Label done;
9429   __ testq(count, count);
9430   __ j(zero, &done);
9431
9432   // Make count the number of bytes to copy.
9433   if (!ascii) {
9434     ASSERT_EQ(2, sizeof(uc16));  // NOLINT
9435     __ addq(count, count);
9436   }
9437
9438   // Don't enter the rep movs if there are less than 4 bytes to copy.
9439   Label last_bytes;
9440   __ testq(count, Immediate(~7));
9441   __ j(zero, &last_bytes);
9442
9443   // Copy from edi to esi using rep movs instruction.
9444   __ movq(kScratchRegister, count);
9445   __ sar(count, Immediate(3));  // Number of doublewords to copy.
9446   __ repmovsq();
9447
9448   // Find number of bytes left.
9449   __ movq(count, kScratchRegister);
9450   __ and_(count, Immediate(7));
9451
9452   // Check if there are more bytes to copy.
9453   __ bind(&last_bytes);
9454   __ testq(count, count);
9455   __ j(zero, &done);
9456
9457   // Copy remaining characters.
9458   Label loop;
9459   __ bind(&loop);
9460   __ movb(kScratchRegister, Operand(src, 0));
9461   __ movb(Operand(dest, 0), kScratchRegister);
9462   __ addq(src, Immediate(1));
9463   __ addq(dest, Immediate(1));
9464   __ subq(count, Immediate(1));
9465   __ j(not_zero, &loop);
9466
9467   __ bind(&done);
9468 }
9469
9470 void StringStubBase::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
9471                                                           Register c1,
9472                                                           Register c2,
9473                                                           Register scratch1,
9474                                                           Register scratch2,
9475                                                           Register scratch3,
9476                                                           Register scratch4,
9477                                                           Label* not_found) {
9478   // Register scratch3 is the general scratch register in this function.
9479   Register scratch = scratch3;
9480
9481   // Make sure that both characters are not digits as such strings has a
9482   // different hash algorithm. Don't try to look for these in the symbol table.
9483   Label not_array_index;
9484   __ movq(scratch, c1);
9485   __ subq(scratch, Immediate(static_cast<int>('0')));
9486   __ cmpq(scratch, Immediate(static_cast<int>('9' - '0')));
9487   __ j(above, &not_array_index);
9488   __ movq(scratch, c2);
9489   __ subq(scratch, Immediate(static_cast<int>('0')));
9490   __ cmpq(scratch, Immediate(static_cast<int>('9' - '0')));
9491   __ j(below_equal, not_found);
9492
9493   __ bind(&not_array_index);
9494   // Calculate the two character string hash.
9495   Register hash = scratch1;
9496   GenerateHashInit(masm, hash, c1, scratch);
9497   GenerateHashAddCharacter(masm, hash, c2, scratch);
9498   GenerateHashGetHash(masm, hash, scratch);
9499
9500   // Collect the two characters in a register.
9501   Register chars = c1;
9502   __ shl(c2, Immediate(kBitsPerByte));
9503   __ orl(chars, c2);
9504
9505   // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
9506   // hash:  hash of two character string.
9507
9508   // Load the symbol table.
9509   Register symbol_table = c2;
9510   __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex);
9511
9512   // Calculate capacity mask from the symbol table capacity.
9513   Register mask = scratch2;
9514   __ movq(mask, FieldOperand(symbol_table, SymbolTable::kCapacityOffset));
9515   __ SmiToInteger32(mask, mask);
9516   __ decl(mask);
9517
9518   Register undefined = scratch4;
9519   __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
9520
9521   // Registers
9522   // chars:        two character string, char 1 in byte 0 and char 2 in byte 1.
9523   // hash:         hash of two character string (32-bit int)
9524   // symbol_table: symbol table
9525   // mask:         capacity mask (32-bit int)
9526   // undefined:    undefined value
9527   // scratch:      -
9528
9529   // Perform a number of probes in the symbol table.
9530   static const int kProbes = 4;
9531   Label found_in_symbol_table;
9532   Label next_probe[kProbes];
9533   for (int i = 0; i < kProbes; i++) {
9534     // Calculate entry in symbol table.
9535     __ movl(scratch, hash);
9536     if (i > 0) {
9537       __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i)));
9538     }
9539     __ andl(scratch, mask);
9540
9541     // Load the entry from the symble table.
9542     Register candidate = scratch;  // Scratch register contains candidate.
9543     ASSERT_EQ(1, SymbolTable::kEntrySize);
9544     __ movq(candidate,
9545            FieldOperand(symbol_table,
9546                         scratch,
9547                         times_pointer_size,
9548                         SymbolTable::kElementsStartOffset));
9549
9550     // If entry is undefined no string with this hash can be found.
9551     __ cmpq(candidate, undefined);
9552     __ j(equal, not_found);
9553
9554     // If length is not 2 the string is not a candidate.
9555     __ cmpl(FieldOperand(candidate, String::kLengthOffset), Immediate(2));
9556     __ j(not_equal, &next_probe[i]);
9557
9558     // We use kScratchRegister as a temporary register in assumption that
9559     // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
9560     Register temp = kScratchRegister;
9561
9562     // Check that the candidate is a non-external ascii string.
9563     __ movq(temp, FieldOperand(candidate, HeapObject::kMapOffset));
9564     __ movzxbl(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
9565     __ JumpIfInstanceTypeIsNotSequentialAscii(
9566         temp, temp, &next_probe[i]);
9567
9568     // Check if the two characters match.
9569     __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize));
9570     __ andl(temp, Immediate(0x0000ffff));
9571     __ cmpl(chars, temp);
9572     __ j(equal, &found_in_symbol_table);
9573     __ bind(&next_probe[i]);
9574   }
9575
9576   // No matching 2 character string found by probing.
9577   __ jmp(not_found);
9578
9579   // Scratch register contains result when we fall through to here.
9580   Register result = scratch;
9581   __ bind(&found_in_symbol_table);
9582   if (!result.is(rax)) {
9583     __ movq(rax, result);
9584   }
9585 }
9586
9587
9588 void StringStubBase::GenerateHashInit(MacroAssembler* masm,
9589                                       Register hash,
9590                                       Register character,
9591                                       Register scratch) {
9592   // hash = character + (character << 10);
9593   __ movl(hash, character);
9594   __ shll(hash, Immediate(10));
9595   __ addl(hash, character);
9596   // hash ^= hash >> 6;
9597   __ movl(scratch, hash);
9598   __ sarl(scratch, Immediate(6));
9599   __ xorl(hash, scratch);
9600 }
9601
9602
9603 void StringStubBase::GenerateHashAddCharacter(MacroAssembler* masm,
9604                                               Register hash,
9605                                               Register character,
9606                                               Register scratch) {
9607   // hash += character;
9608   __ addl(hash, character);
9609   // hash += hash << 10;
9610   __ movl(scratch, hash);
9611   __ shll(scratch, Immediate(10));
9612   __ addl(hash, scratch);
9613   // hash ^= hash >> 6;
9614   __ movl(scratch, hash);
9615   __ sarl(scratch, Immediate(6));
9616   __ xorl(hash, scratch);
9617 }
9618
9619
9620 void StringStubBase::GenerateHashGetHash(MacroAssembler* masm,
9621                                          Register hash,
9622                                          Register scratch) {
9623   // hash += hash << 3;
9624   __ movl(scratch, hash);
9625   __ shll(scratch, Immediate(3));
9626   __ addl(hash, scratch);
9627   // hash ^= hash >> 11;
9628   __ movl(scratch, hash);
9629   __ sarl(scratch, Immediate(11));
9630   __ xorl(hash, scratch);
9631   // hash += hash << 15;
9632   __ movl(scratch, hash);
9633   __ shll(scratch, Immediate(15));
9634   __ addl(hash, scratch);
9635
9636   // if (hash == 0) hash = 27;
9637   Label hash_not_zero;
9638   __ testl(hash, hash);
9639   __ j(not_zero, &hash_not_zero);
9640   __ movl(hash, Immediate(27));
9641   __ bind(&hash_not_zero);
9642 }
9643
9644 void SubStringStub::Generate(MacroAssembler* masm) {
9645   Label runtime;
9646
9647   // Stack frame on entry.
9648   //  rsp[0]: return address
9649   //  rsp[8]: to
9650   //  rsp[16]: from
9651   //  rsp[24]: string
9652
9653   const int kToOffset = 1 * kPointerSize;
9654   const int kFromOffset = kToOffset + kPointerSize;
9655   const int kStringOffset = kFromOffset + kPointerSize;
9656   const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
9657
9658   // Make sure first argument is a string.
9659   __ movq(rax, Operand(rsp, kStringOffset));
9660   ASSERT_EQ(0, kSmiTag);
9661   __ testl(rax, Immediate(kSmiTagMask));
9662   __ j(zero, &runtime);
9663   Condition is_string = masm->IsObjectStringType(rax, rbx, rbx);
9664   __ j(NegateCondition(is_string), &runtime);
9665
9666   // rax: string
9667   // rbx: instance type
9668   // Calculate length of sub string using the smi values.
9669   Label result_longer_than_two;
9670   __ movq(rcx, Operand(rsp, kToOffset));
9671   __ movq(rdx, Operand(rsp, kFromOffset));
9672   __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime);
9673
9674   __ SmiSub(rcx, rcx, rdx, NULL);  // Overflow doesn't happen.
9675   __ j(negative, &runtime);
9676   // Special handling of sub-strings of length 1 and 2. One character strings
9677   // are handled in the runtime system (looked up in the single character
9678   // cache). Two character strings are looked for in the symbol cache.
9679   __ SmiToInteger32(rcx, rcx);
9680   __ cmpl(rcx, Immediate(2));
9681   __ j(greater, &result_longer_than_two);
9682   __ j(less, &runtime);
9683
9684   // Sub string of length 2 requested.
9685   // rax: string
9686   // rbx: instance type
9687   // rcx: sub string length (value is 2)
9688   // rdx: from index (smi)
9689   __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &runtime);
9690
9691   // Get the two characters forming the sub string.
9692   __ SmiToInteger32(rdx, rdx);  // From index is no longer smi.
9693   __ movzxbq(rbx, FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize));
9694   __ movzxbq(rcx,
9695              FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize + 1));
9696
9697   // Try to lookup two character string in symbol table.
9698   Label make_two_character_string;
9699   GenerateTwoCharacterSymbolTableProbe(masm, rbx, rcx, rax, rdx, rdi, r14,
9700                                        &make_two_character_string);
9701   __ ret(3 * kPointerSize);
9702
9703   __ bind(&make_two_character_string);
9704   // Setup registers for allocating the two character string.
9705   __ movq(rax, Operand(rsp, kStringOffset));
9706   __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
9707   __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
9708   __ Set(rcx, 2);
9709
9710   __ bind(&result_longer_than_two);
9711
9712   // rax: string
9713   // rbx: instance type
9714   // rcx: result string length
9715   // Check for flat ascii string
9716   Label non_ascii_flat;
9717   __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &non_ascii_flat);
9718
9719   // Allocate the result.
9720   __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime);
9721
9722   // rax: result string
9723   // rcx: result string length
9724   __ movq(rdx, rsi);  // esi used by following code.
9725   // Locate first character of result.
9726   __ lea(rdi, FieldOperand(rax, SeqAsciiString::kHeaderSize));
9727   // Load string argument and locate character of sub string start.
9728   __ movq(rsi, Operand(rsp, kStringOffset));
9729   __ movq(rbx, Operand(rsp, kFromOffset));
9730   {
9731     SmiIndex smi_as_index = masm->SmiToIndex(rbx, rbx, times_1);
9732     __ lea(rsi, Operand(rsi, smi_as_index.reg, smi_as_index.scale,
9733                         SeqAsciiString::kHeaderSize - kHeapObjectTag));
9734   }
9735
9736   // rax: result string
9737   // rcx: result length
9738   // rdx: original value of rsi
9739   // rdi: first character of result
9740   // rsi: character of sub string start
9741   GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
9742   __ movq(rsi, rdx);  // Restore rsi.
9743   __ IncrementCounter(&Counters::sub_string_native, 1);
9744   __ ret(kArgumentsSize);
9745
9746   __ bind(&non_ascii_flat);
9747   // rax: string
9748   // rbx: instance type & kStringRepresentationMask | kStringEncodingMask
9749   // rcx: result string length
9750   // Check for sequential two byte string
9751   __ cmpb(rbx, Immediate(kSeqStringTag | kTwoByteStringTag));
9752   __ j(not_equal, &runtime);
9753
9754   // Allocate the result.
9755   __ AllocateTwoByteString(rax, rcx, rbx, rdx, rdi, &runtime);
9756
9757   // rax: result string
9758   // rcx: result string length
9759   __ movq(rdx, rsi);  // esi used by following code.
9760   // Locate first character of result.
9761   __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize));
9762   // Load string argument and locate character of sub string start.
9763   __ movq(rsi, Operand(rsp, kStringOffset));
9764   __ movq(rbx, Operand(rsp, kFromOffset));
9765   {
9766     SmiIndex smi_as_index = masm->SmiToIndex(rbx, rbx, times_2);
9767     __ lea(rsi, Operand(rsi, smi_as_index.reg, smi_as_index.scale,
9768                         SeqAsciiString::kHeaderSize - kHeapObjectTag));
9769   }
9770
9771   // rax: result string
9772   // rcx: result length
9773   // rdx: original value of rsi
9774   // rdi: first character of result
9775   // rsi: character of sub string start
9776   GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false);
9777   __ movq(rsi, rdx);  // Restore esi.
9778   __ IncrementCounter(&Counters::sub_string_native, 1);
9779   __ ret(kArgumentsSize);
9780
9781   // Just jump to runtime to create the sub string.
9782   __ bind(&runtime);
9783   __ TailCallRuntime(Runtime::kSubString, 3, 1);
9784 }
9785
9786
9787 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
9788                                                         Register left,
9789                                                         Register right,
9790                                                         Register scratch1,
9791                                                         Register scratch2,
9792                                                         Register scratch3,
9793                                                         Register scratch4) {
9794   // Ensure that you can always subtract a string length from a non-negative
9795   // number (e.g. another length).
9796   ASSERT(String::kMaxLength < 0x7fffffff);
9797
9798   // Find minimum length and length difference.
9799   __ movl(scratch1, FieldOperand(left, String::kLengthOffset));
9800   __ movl(scratch4, scratch1);
9801   __ subl(scratch4, FieldOperand(right, String::kLengthOffset));
9802   // Register scratch4 now holds left.length - right.length.
9803   const Register length_difference = scratch4;
9804   Label left_shorter;
9805   __ j(less, &left_shorter);
9806   // The right string isn't longer that the left one.
9807   // Get the right string's length by subtracting the (non-negative) difference
9808   // from the left string's length.
9809   __ subl(scratch1, length_difference);
9810   __ bind(&left_shorter);
9811   // Register scratch1 now holds Min(left.length, right.length).
9812   const Register min_length = scratch1;
9813
9814   Label compare_lengths;
9815   // If min-length is zero, go directly to comparing lengths.
9816   __ testl(min_length, min_length);
9817   __ j(zero, &compare_lengths);
9818
9819   // Registers scratch2 and scratch3 are free.
9820   Label result_not_equal;
9821   Label loop;
9822   {
9823     // Check characters 0 .. min_length - 1 in a loop.
9824     // Use scratch3 as loop index, min_length as limit and scratch2
9825     // for computation.
9826     const Register index = scratch3;
9827     __ movl(index, Immediate(0));  // Index into strings.
9828     __ bind(&loop);
9829     // Compare characters.
9830     // TODO(lrn): Could we load more than one character at a time?
9831     __ movb(scratch2, FieldOperand(left,
9832                                    index,
9833                                    times_1,
9834                                    SeqAsciiString::kHeaderSize));
9835     // Increment index and use -1 modifier on next load to give
9836     // the previous load extra time to complete.
9837     __ addl(index, Immediate(1));
9838     __ cmpb(scratch2, FieldOperand(right,
9839                                    index,
9840                                    times_1,
9841                                    SeqAsciiString::kHeaderSize - 1));
9842     __ j(not_equal, &result_not_equal);
9843     __ cmpl(index, min_length);
9844     __ j(not_equal, &loop);
9845   }
9846   // Completed loop without finding different characters.
9847   // Compare lengths (precomputed).
9848   __ bind(&compare_lengths);
9849   __ testl(length_difference, length_difference);
9850   __ j(not_zero, &result_not_equal);
9851
9852   // Result is EQUAL.
9853   __ Move(rax, Smi::FromInt(EQUAL));
9854   __ ret(2 * kPointerSize);
9855
9856   Label result_greater;
9857   __ bind(&result_not_equal);
9858   // Unequal comparison of left to right, either character or length.
9859   __ j(greater, &result_greater);
9860
9861   // Result is LESS.
9862   __ Move(rax, Smi::FromInt(LESS));
9863   __ ret(2 * kPointerSize);
9864
9865   // Result is GREATER.
9866   __ bind(&result_greater);
9867   __ Move(rax, Smi::FromInt(GREATER));
9868   __ ret(2 * kPointerSize);
9869 }
9870
9871
9872 void StringCompareStub::Generate(MacroAssembler* masm) {
9873   Label runtime;
9874
9875   // Stack frame on entry.
9876   //  rsp[0]: return address
9877   //  rsp[8]: right string
9878   //  rsp[16]: left string
9879
9880   __ movq(rdx, Operand(rsp, 2 * kPointerSize));  // left
9881   __ movq(rax, Operand(rsp, 1 * kPointerSize));  // right
9882
9883   // Check for identity.
9884   Label not_same;
9885   __ cmpq(rdx, rax);
9886   __ j(not_equal, &not_same);
9887   __ Move(rax, Smi::FromInt(EQUAL));
9888   __ IncrementCounter(&Counters::string_compare_native, 1);
9889   __ ret(2 * kPointerSize);
9890
9891   __ bind(&not_same);
9892
9893   // Check that both are sequential ASCII strings.
9894   __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime);
9895
9896   // Inline comparison of ascii strings.
9897   __ IncrementCounter(&Counters::string_compare_native, 1);
9898   GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8);
9899
9900   // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
9901   // tagged as a small integer.
9902   __ bind(&runtime);
9903   __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
9904 }
9905
9906 #undef __
9907
9908 #define __ masm.
9909
9910 #ifdef _WIN64
9911 typedef double (*ModuloFunction)(double, double);
9912 // Define custom fmod implementation.
9913 ModuloFunction CreateModuloFunction() {
9914   size_t actual_size;
9915   byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
9916                                                  &actual_size,
9917                                                  true));
9918   CHECK(buffer);
9919   Assembler masm(buffer, static_cast<int>(actual_size));
9920   // Generated code is put into a fixed, unmovable, buffer, and not into
9921   // the V8 heap. We can't, and don't, refer to any relocatable addresses
9922   // (e.g. the JavaScript nan-object).
9923
9924   // Windows 64 ABI passes double arguments in xmm0, xmm1 and
9925   // returns result in xmm0.
9926   // Argument backing space is allocated on the stack above
9927   // the return address.
9928
9929   // Compute x mod y.
9930   // Load y and x (use argument backing store as temporary storage).
9931   __ movsd(Operand(rsp, kPointerSize * 2), xmm1);
9932   __ movsd(Operand(rsp, kPointerSize), xmm0);
9933   __ fld_d(Operand(rsp, kPointerSize * 2));
9934   __ fld_d(Operand(rsp, kPointerSize));
9935
9936   // Clear exception flags before operation.
9937   {
9938     Label no_exceptions;
9939     __ fwait();
9940     __ fnstsw_ax();
9941     // Clear if Illegal Operand or Zero Division exceptions are set.
9942     __ testb(rax, Immediate(5));
9943     __ j(zero, &no_exceptions);
9944     __ fnclex();
9945     __ bind(&no_exceptions);
9946   }
9947
9948   // Compute st(0) % st(1)
9949   {
9950     Label partial_remainder_loop;
9951     __ bind(&partial_remainder_loop);
9952     __ fprem();
9953     __ fwait();
9954     __ fnstsw_ax();
9955     __ testl(rax, Immediate(0x400 /* C2 */));
9956     // If C2 is set, computation only has partial result. Loop to
9957     // continue computation.
9958     __ j(not_zero, &partial_remainder_loop);
9959   }
9960
9961   Label valid_result;
9962   Label return_result;
9963   // If Invalid Operand or Zero Division exceptions are set,
9964   // return NaN.
9965   __ testb(rax, Immediate(5));
9966   __ j(zero, &valid_result);
9967   __ fstp(0);  // Drop result in st(0).
9968   int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
9969   __ movq(rcx, kNaNValue, RelocInfo::NONE);
9970   __ movq(Operand(rsp, kPointerSize), rcx);
9971   __ movsd(xmm0, Operand(rsp, kPointerSize));
9972   __ jmp(&return_result);
9973
9974   // If result is valid, return that.
9975   __ bind(&valid_result);
9976   __ fstp_d(Operand(rsp, kPointerSize));
9977   __ movsd(xmm0, Operand(rsp, kPointerSize));
9978
9979   // Clean up FPU stack and exceptions and return xmm0
9980   __ bind(&return_result);
9981   __ fstp(0);  // Unload y.
9982
9983   Label clear_exceptions;
9984   __ testb(rax, Immediate(0x3f /* Any Exception*/));
9985   __ j(not_zero, &clear_exceptions);
9986   __ ret(0);
9987   __ bind(&clear_exceptions);
9988   __ fnclex();
9989   __ ret(0);
9990
9991   CodeDesc desc;
9992   masm.GetCode(&desc);
9993   // Call the function from C++.
9994   return FUNCTION_CAST<ModuloFunction>(buffer);
9995 }
9996
9997 #endif
9998
9999
10000 #undef __
10001
10002 } }  // namespace v8::internal