[builtins] Add support for NewTarget to Execution::New.
[platform/upstream/v8.git] / src / full-codegen / mips / full-codegen-mips.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #if V8_TARGET_ARCH_MIPS
6
7 // Note on Mips implementation:
8 //
9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first
11 // parameter to a function is defined to be 'a0'. So there are many
12 // places where we have to move a previous result in v0 to a0 for the
13 // next call: mov(a0, v0). This is not needed on the other architectures.
14
15 #include "src/code-factory.h"
16 #include "src/code-stubs.h"
17 #include "src/codegen.h"
18 #include "src/compiler.h"
19 #include "src/debug/debug.h"
20 #include "src/full-codegen/full-codegen.h"
21 #include "src/ic/ic.h"
22 #include "src/parser.h"
23 #include "src/scopes.h"
24
25 #include "src/mips/code-stubs-mips.h"
26 #include "src/mips/macro-assembler-mips.h"
27
28 namespace v8 {
29 namespace internal {
30
31 #define __ ACCESS_MASM(masm_)
32
33
34 // A patch site is a location in the code which it is possible to patch. This
35 // class has a number of methods to emit the code which is patchable and the
36 // method EmitPatchInfo to record a marker back to the patchable code. This
37 // marker is a andi zero_reg, rx, #yyyy instruction, and rx * 0x0000ffff + yyyy
38 // (raw 16 bit immediate value is used) is the delta from the pc to the first
39 // instruction of the patchable code.
40 // The marker instruction is effectively a NOP (dest is zero_reg) and will
41 // never be emitted by normal code.
42 class JumpPatchSite BASE_EMBEDDED {
43  public:
44   explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
45 #ifdef DEBUG
46     info_emitted_ = false;
47 #endif
48   }
49
50   ~JumpPatchSite() {
51     DCHECK(patch_site_.is_bound() == info_emitted_);
52   }
53
54   // When initially emitting this ensure that a jump is always generated to skip
55   // the inlined smi code.
56   void EmitJumpIfNotSmi(Register reg, Label* target) {
57     DCHECK(!patch_site_.is_bound() && !info_emitted_);
58     Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
59     __ bind(&patch_site_);
60     __ andi(at, reg, 0);
61     // Always taken before patched.
62     __ BranchShort(target, eq, at, Operand(zero_reg));
63   }
64
65   // When initially emitting this ensure that a jump is never generated to skip
66   // the inlined smi code.
67   void EmitJumpIfSmi(Register reg, Label* target) {
68     Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
69     DCHECK(!patch_site_.is_bound() && !info_emitted_);
70     __ bind(&patch_site_);
71     __ andi(at, reg, 0);
72     // Never taken before patched.
73     __ BranchShort(target, ne, at, Operand(zero_reg));
74   }
75
76   void EmitPatchInfo() {
77     if (patch_site_.is_bound()) {
78       int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
79       Register reg = Register::from_code(delta_to_patch_site / kImm16Mask);
80       __ andi(zero_reg, reg, delta_to_patch_site % kImm16Mask);
81 #ifdef DEBUG
82       info_emitted_ = true;
83 #endif
84     } else {
85       __ nop();  // Signals no inlined code.
86     }
87   }
88
89  private:
90   MacroAssembler* masm_;
91   Label patch_site_;
92 #ifdef DEBUG
93   bool info_emitted_;
94 #endif
95 };
96
97
98 // Generate code for a JS function.  On entry to the function the receiver
99 // and arguments have been pushed on the stack left to right.  The actual
100 // argument count matches the formal parameter count expected by the
101 // function.
102 //
103 // The live registers are:
104 //   o a1: the JS function object being called (i.e. ourselves)
105 //   o cp: our context
106 //   o fp: our caller's frame pointer
107 //   o sp: stack pointer
108 //   o ra: return address
109 //
110 // The function builds a JS frame.  Please see JavaScriptFrameConstants in
111 // frames-mips.h for its layout.
112 void FullCodeGenerator::Generate() {
113   CompilationInfo* info = info_;
114   profiling_counter_ = isolate()->factory()->NewCell(
115       Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
116   SetFunctionPosition(literal());
117   Comment cmnt(masm_, "[ function compiled by full code generator");
118
119   ProfileEntryHookStub::MaybeCallEntryHook(masm_);
120
121 #ifdef DEBUG
122   if (strlen(FLAG_stop_at) > 0 &&
123       info->literal()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
124     __ stop("stop-at");
125   }
126 #endif
127
128   // Sloppy mode functions and builtins need to replace the receiver with the
129   // global proxy when called as functions (without an explicit receiver
130   // object).
131   if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) {
132     Label ok;
133     int receiver_offset = info->scope()->num_parameters() * kPointerSize;
134     __ lw(at, MemOperand(sp, receiver_offset));
135     __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
136     __ Branch(&ok, ne, a2, Operand(at));
137
138     __ lw(a2, GlobalObjectOperand());
139     __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
140
141     __ sw(a2, MemOperand(sp, receiver_offset));
142
143     __ bind(&ok);
144   }
145
146   // Open a frame scope to indicate that there is a frame on the stack.  The
147   // MANUAL indicates that the scope shouldn't actually generate code to set up
148   // the frame (that is done below).
149   FrameScope frame_scope(masm_, StackFrame::MANUAL);
150
151   info->set_prologue_offset(masm_->pc_offset());
152   __ Prologue(info->IsCodePreAgingActive());
153   info->AddNoFrameRange(0, masm_->pc_offset());
154
155   { Comment cmnt(masm_, "[ Allocate locals");
156     int locals_count = info->scope()->num_stack_slots();
157     // Generators allocate locals, if any, in context slots.
158     DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
159     if (locals_count > 0) {
160       if (locals_count >= 128) {
161         Label ok;
162         __ Subu(t5, sp, Operand(locals_count * kPointerSize));
163         __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
164         __ Branch(&ok, hs, t5, Operand(a2));
165         __ CallRuntime(Runtime::kThrowStackOverflow, 0);
166         __ bind(&ok);
167       }
168       __ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
169       int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
170       if (locals_count >= kMaxPushes) {
171         int loop_iterations = locals_count / kMaxPushes;
172         __ li(a2, Operand(loop_iterations));
173         Label loop_header;
174         __ bind(&loop_header);
175         // Do pushes.
176         __ Subu(sp, sp, Operand(kMaxPushes * kPointerSize));
177         for (int i = 0; i < kMaxPushes; i++) {
178           __ sw(t5, MemOperand(sp, i * kPointerSize));
179         }
180         // Continue loop if not done.
181         __ Subu(a2, a2, Operand(1));
182         __ Branch(&loop_header, ne, a2, Operand(zero_reg));
183       }
184       int remaining = locals_count % kMaxPushes;
185       // Emit the remaining pushes.
186       __ Subu(sp, sp, Operand(remaining * kPointerSize));
187       for (int i  = 0; i < remaining; i++) {
188         __ sw(t5, MemOperand(sp, i * kPointerSize));
189       }
190     }
191   }
192
193   bool function_in_register_a1 = true;
194
195   // Possibly allocate a local context.
196   if (info->scope()->num_heap_slots() > 0) {
197     Comment cmnt(masm_, "[ Allocate context");
198     // Argument to NewContext is the function, which is still in a1.
199     bool need_write_barrier = true;
200     int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
201     if (info->scope()->is_script_scope()) {
202       __ push(a1);
203       __ Push(info->scope()->GetScopeInfo(info->isolate()));
204       __ CallRuntime(Runtime::kNewScriptContext, 2);
205     } else if (slots <= FastNewContextStub::kMaximumSlots) {
206       FastNewContextStub stub(isolate(), slots);
207       __ CallStub(&stub);
208       // Result of FastNewContextStub is always in new space.
209       need_write_barrier = false;
210     } else {
211       __ push(a1);
212       __ CallRuntime(Runtime::kNewFunctionContext, 1);
213     }
214     function_in_register_a1 = false;
215     // Context is returned in v0. It replaces the context passed to us.
216     // It's saved in the stack and kept live in cp.
217     __ mov(cp, v0);
218     __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset));
219     // Copy any necessary parameters into the context.
220     int num_parameters = info->scope()->num_parameters();
221     int first_parameter = info->scope()->has_this_declaration() ? -1 : 0;
222     for (int i = first_parameter; i < num_parameters; i++) {
223       Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i);
224       if (var->IsContextSlot()) {
225         int parameter_offset = StandardFrameConstants::kCallerSPOffset +
226                                  (num_parameters - 1 - i) * kPointerSize;
227         // Load parameter from stack.
228         __ lw(a0, MemOperand(fp, parameter_offset));
229         // Store it in the context.
230         MemOperand target = ContextOperand(cp, var->index());
231         __ sw(a0, target);
232
233         // Update the write barrier.
234         if (need_write_barrier) {
235           __ RecordWriteContextSlot(
236               cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs);
237         } else if (FLAG_debug_code) {
238           Label done;
239           __ JumpIfInNewSpace(cp, a0, &done);
240           __ Abort(kExpectedNewSpaceObject);
241           __ bind(&done);
242         }
243       }
244     }
245   }
246
247   PrepareForBailoutForId(BailoutId::Prologue(), NO_REGISTERS);
248   // Function register is trashed in case we bailout here. But since that
249   // could happen only when we allocate a context the value of
250   // |function_in_register_a1| is correct.
251
252   // Possibly set up a local binding to the this function which is used in
253   // derived constructors with super calls.
254   Variable* this_function_var = scope()->this_function_var();
255   if (this_function_var != nullptr) {
256     Comment cmnt(masm_, "[ This function");
257     if (!function_in_register_a1) {
258       __ lw(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
259       // The write barrier clobbers register again, keep it marked as such.
260     }
261     SetVar(this_function_var, a1, a2, a3);
262   }
263
264   Variable* new_target_var = scope()->new_target_var();
265   if (new_target_var != nullptr) {
266     Comment cmnt(masm_, "[ new.target");
267
268     // Get the frame pointer for the calling frame.
269     __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
270
271     // Skip the arguments adaptor frame if it exists.
272     Label check_frame_marker;
273     __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset));
274     __ Branch(&check_frame_marker, ne, a1,
275               Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
276     __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
277
278     // Check the marker in the calling frame.
279     __ bind(&check_frame_marker);
280     __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset));
281     function_in_register_a1 = false;
282
283     Label non_construct_frame, done;
284     __ Branch(&non_construct_frame, ne, a1,
285               Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
286
287     __ lw(v0,
288           MemOperand(a2, ConstructFrameConstants::kOriginalConstructorOffset));
289     __ Branch(&done);
290
291     __ bind(&non_construct_frame);
292     __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
293     __ bind(&done);
294
295     SetVar(new_target_var, v0, a2, a3);
296   }
297
298   Variable* arguments = scope()->arguments();
299   if (arguments != NULL) {
300     // Function uses arguments object.
301     Comment cmnt(masm_, "[ Allocate arguments object");
302     if (!function_in_register_a1) {
303       // Load this again, if it's used by the local context below.
304       __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
305     } else {
306       __ mov(a3, a1);
307     }
308     // Receiver is just before the parameters on the caller's stack.
309     int num_parameters = info->scope()->num_parameters();
310     int offset = num_parameters * kPointerSize;
311     __ Addu(a2, fp,
312            Operand(StandardFrameConstants::kCallerSPOffset + offset));
313     __ li(a1, Operand(Smi::FromInt(num_parameters)));
314     __ Push(a3, a2, a1);
315
316     // Arguments to ArgumentsAccessStub:
317     //   function, receiver address, parameter count.
318     // The stub will rewrite receiever and parameter count if the previous
319     // stack frame was an arguments adapter frame.
320     ArgumentsAccessStub::Type type;
321     if (is_strict(language_mode()) || !has_simple_parameters()) {
322       type = ArgumentsAccessStub::NEW_STRICT;
323     } else if (literal()->has_duplicate_parameters()) {
324       type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
325     } else {
326       type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
327     }
328     ArgumentsAccessStub stub(isolate(), type);
329     __ CallStub(&stub);
330
331     SetVar(arguments, v0, a1, a2);
332   }
333
334   if (FLAG_trace) {
335     __ CallRuntime(Runtime::kTraceEnter, 0);
336   }
337
338   // Visit the declarations and body unless there is an illegal
339   // redeclaration.
340   if (scope()->HasIllegalRedeclaration()) {
341     Comment cmnt(masm_, "[ Declarations");
342     VisitForEffect(scope()->GetIllegalRedeclaration());
343
344   } else {
345     PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
346     { Comment cmnt(masm_, "[ Declarations");
347       VisitDeclarations(scope()->declarations());
348     }
349
350     // Assert that the declarations do not use ICs. Otherwise the debugger
351     // won't be able to redirect a PC at an IC to the correct IC in newly
352     // recompiled code.
353     DCHECK_EQ(0, ic_total_count_);
354
355     { Comment cmnt(masm_, "[ Stack check");
356       PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
357       Label ok;
358       __ LoadRoot(at, Heap::kStackLimitRootIndex);
359       __ Branch(&ok, hs, sp, Operand(at));
360       Handle<Code> stack_check = isolate()->builtins()->StackCheck();
361       PredictableCodeSizeScope predictable(masm_,
362           masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
363       __ Call(stack_check, RelocInfo::CODE_TARGET);
364       __ bind(&ok);
365     }
366
367     { Comment cmnt(masm_, "[ Body");
368       DCHECK(loop_depth() == 0);
369       VisitStatements(literal()->body());
370       DCHECK(loop_depth() == 0);
371     }
372   }
373
374   // Always emit a 'return undefined' in case control fell off the end of
375   // the body.
376   { Comment cmnt(masm_, "[ return <undefined>;");
377     __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
378   }
379   EmitReturnSequence();
380 }
381
382
383 void FullCodeGenerator::ClearAccumulator() {
384   DCHECK(Smi::FromInt(0) == 0);
385   __ mov(v0, zero_reg);
386 }
387
388
389 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
390   __ li(a2, Operand(profiling_counter_));
391   __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
392   __ Subu(a3, a3, Operand(Smi::FromInt(delta)));
393   __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
394 }
395
396
397 void FullCodeGenerator::EmitProfilingCounterReset() {
398   int reset_value = FLAG_interrupt_budget;
399   if (info_->is_debug()) {
400     // Detect debug break requests as soon as possible.
401     reset_value = FLAG_interrupt_budget >> 4;
402   }
403   __ li(a2, Operand(profiling_counter_));
404   __ li(a3, Operand(Smi::FromInt(reset_value)));
405   __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
406 }
407
408
409 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
410                                                 Label* back_edge_target) {
411   // The generated code is used in Deoptimizer::PatchStackCheckCodeAt so we need
412   // to make sure it is constant. Branch may emit a skip-or-jump sequence
413   // instead of the normal Branch. It seems that the "skip" part of that
414   // sequence is about as long as this Branch would be so it is safe to ignore
415   // that.
416   Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
417   Comment cmnt(masm_, "[ Back edge bookkeeping");
418   Label ok;
419   DCHECK(back_edge_target->is_bound());
420   int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
421   int weight = Min(kMaxBackEdgeWeight,
422                    Max(1, distance / kCodeSizeMultiplier));
423   EmitProfilingCounterDecrement(weight);
424   __ slt(at, a3, zero_reg);
425   __ beq(at, zero_reg, &ok);
426   // Call will emit a li t9 first, so it is safe to use the delay slot.
427   __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
428   // Record a mapping of this PC offset to the OSR id.  This is used to find
429   // the AST id from the unoptimized code in order to use it as a key into
430   // the deoptimization input data found in the optimized code.
431   RecordBackEdge(stmt->OsrEntryId());
432   EmitProfilingCounterReset();
433
434   __ bind(&ok);
435   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
436   // Record a mapping of the OSR id to this PC.  This is used if the OSR
437   // entry becomes the target of a bailout.  We don't expect it to be, but
438   // we want it to work if it is.
439   PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
440 }
441
442
443 void FullCodeGenerator::EmitReturnSequence() {
444   Comment cmnt(masm_, "[ Return sequence");
445   if (return_label_.is_bound()) {
446     __ Branch(&return_label_);
447   } else {
448     __ bind(&return_label_);
449     if (FLAG_trace) {
450       // Push the return value on the stack as the parameter.
451       // Runtime::TraceExit returns its parameter in v0.
452       __ push(v0);
453       __ CallRuntime(Runtime::kTraceExit, 1);
454     }
455     // Pretend that the exit is a backwards jump to the entry.
456     int weight = 1;
457     if (info_->ShouldSelfOptimize()) {
458       weight = FLAG_interrupt_budget / FLAG_self_opt_count;
459     } else {
460       int distance = masm_->pc_offset();
461       weight = Min(kMaxBackEdgeWeight,
462                    Max(1, distance / kCodeSizeMultiplier));
463     }
464     EmitProfilingCounterDecrement(weight);
465     Label ok;
466     __ Branch(&ok, ge, a3, Operand(zero_reg));
467     __ push(v0);
468     __ Call(isolate()->builtins()->InterruptCheck(),
469             RelocInfo::CODE_TARGET);
470     __ pop(v0);
471     EmitProfilingCounterReset();
472     __ bind(&ok);
473
474     // Make sure that the constant pool is not emitted inside of the return
475     // sequence.
476     { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
477       // Here we use masm_-> instead of the __ macro to avoid the code coverage
478       // tool from instrumenting as we rely on the code size here.
479       int32_t arg_count = info_->scope()->num_parameters() + 1;
480       int32_t sp_delta = arg_count * kPointerSize;
481       SetReturnPosition(literal());
482       masm_->mov(sp, fp);
483       int no_frame_start = masm_->pc_offset();
484       masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit()));
485       masm_->Addu(sp, sp, Operand(sp_delta));
486       masm_->Jump(ra);
487       info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
488     }
489   }
490 }
491
492
493 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
494   DCHECK(var->IsStackAllocated() || var->IsContextSlot());
495   codegen()->GetVar(result_register(), var);
496   __ push(result_register());
497 }
498
499
500 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
501 }
502
503
504 void FullCodeGenerator::AccumulatorValueContext::Plug(
505     Heap::RootListIndex index) const {
506   __ LoadRoot(result_register(), index);
507 }
508
509
510 void FullCodeGenerator::StackValueContext::Plug(
511     Heap::RootListIndex index) const {
512   __ LoadRoot(result_register(), index);
513   __ push(result_register());
514 }
515
516
517 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
518   codegen()->PrepareForBailoutBeforeSplit(condition(),
519                                           true,
520                                           true_label_,
521                                           false_label_);
522   if (index == Heap::kUndefinedValueRootIndex ||
523       index == Heap::kNullValueRootIndex ||
524       index == Heap::kFalseValueRootIndex) {
525     if (false_label_ != fall_through_) __ Branch(false_label_);
526   } else if (index == Heap::kTrueValueRootIndex) {
527     if (true_label_ != fall_through_) __ Branch(true_label_);
528   } else {
529     __ LoadRoot(result_register(), index);
530     codegen()->DoTest(this);
531   }
532 }
533
534
535 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {
536 }
537
538
539 void FullCodeGenerator::AccumulatorValueContext::Plug(
540     Handle<Object> lit) const {
541   __ li(result_register(), Operand(lit));
542 }
543
544
545 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
546   // Immediates cannot be pushed directly.
547   __ li(result_register(), Operand(lit));
548   __ push(result_register());
549 }
550
551
552 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
553   codegen()->PrepareForBailoutBeforeSplit(condition(),
554                                           true,
555                                           true_label_,
556                                           false_label_);
557   DCHECK(!lit->IsUndetectableObject());  // There are no undetectable literals.
558   if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
559     if (false_label_ != fall_through_) __ Branch(false_label_);
560   } else if (lit->IsTrue() || lit->IsJSObject()) {
561     if (true_label_ != fall_through_) __ Branch(true_label_);
562   } else if (lit->IsString()) {
563     if (String::cast(*lit)->length() == 0) {
564       if (false_label_ != fall_through_) __ Branch(false_label_);
565     } else {
566       if (true_label_ != fall_through_) __ Branch(true_label_);
567     }
568   } else if (lit->IsSmi()) {
569     if (Smi::cast(*lit)->value() == 0) {
570       if (false_label_ != fall_through_) __ Branch(false_label_);
571     } else {
572       if (true_label_ != fall_through_) __ Branch(true_label_);
573     }
574   } else {
575     // For simplicity we always test the accumulator register.
576     __ li(result_register(), Operand(lit));
577     codegen()->DoTest(this);
578   }
579 }
580
581
582 void FullCodeGenerator::EffectContext::DropAndPlug(int count,
583                                                    Register reg) const {
584   DCHECK(count > 0);
585   __ Drop(count);
586 }
587
588
589 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
590     int count,
591     Register reg) const {
592   DCHECK(count > 0);
593   __ Drop(count);
594   __ Move(result_register(), reg);
595 }
596
597
598 void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
599                                                        Register reg) const {
600   DCHECK(count > 0);
601   if (count > 1) __ Drop(count - 1);
602   __ sw(reg, MemOperand(sp, 0));
603 }
604
605
606 void FullCodeGenerator::TestContext::DropAndPlug(int count,
607                                                  Register reg) const {
608   DCHECK(count > 0);
609   // For simplicity we always test the accumulator register.
610   __ Drop(count);
611   __ Move(result_register(), reg);
612   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
613   codegen()->DoTest(this);
614 }
615
616
617 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
618                                             Label* materialize_false) const {
619   DCHECK(materialize_true == materialize_false);
620   __ bind(materialize_true);
621 }
622
623
624 void FullCodeGenerator::AccumulatorValueContext::Plug(
625     Label* materialize_true,
626     Label* materialize_false) const {
627   Label done;
628   __ bind(materialize_true);
629   __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
630   __ Branch(&done);
631   __ bind(materialize_false);
632   __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
633   __ bind(&done);
634 }
635
636
637 void FullCodeGenerator::StackValueContext::Plug(
638     Label* materialize_true,
639     Label* materialize_false) const {
640   Label done;
641   __ bind(materialize_true);
642   __ LoadRoot(at, Heap::kTrueValueRootIndex);
643   // Push the value as the following branch can clobber at in long branch mode.
644   __ push(at);
645   __ Branch(&done);
646   __ bind(materialize_false);
647   __ LoadRoot(at, Heap::kFalseValueRootIndex);
648   __ push(at);
649   __ bind(&done);
650 }
651
652
653 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
654                                           Label* materialize_false) const {
655   DCHECK(materialize_true == true_label_);
656   DCHECK(materialize_false == false_label_);
657 }
658
659
660 void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
661   Heap::RootListIndex value_root_index =
662       flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
663   __ LoadRoot(result_register(), value_root_index);
664 }
665
666
667 void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
668   Heap::RootListIndex value_root_index =
669       flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
670   __ LoadRoot(at, value_root_index);
671   __ push(at);
672 }
673
674
675 void FullCodeGenerator::TestContext::Plug(bool flag) const {
676   codegen()->PrepareForBailoutBeforeSplit(condition(),
677                                           true,
678                                           true_label_,
679                                           false_label_);
680   if (flag) {
681     if (true_label_ != fall_through_) __ Branch(true_label_);
682   } else {
683     if (false_label_ != fall_through_) __ Branch(false_label_);
684   }
685 }
686
687
688 void FullCodeGenerator::DoTest(Expression* condition,
689                                Label* if_true,
690                                Label* if_false,
691                                Label* fall_through) {
692   __ mov(a0, result_register());
693   Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
694   CallIC(ic, condition->test_id());
695   __ mov(at, zero_reg);
696   Split(ne, v0, Operand(at), if_true, if_false, fall_through);
697 }
698
699
700 void FullCodeGenerator::Split(Condition cc,
701                               Register lhs,
702                               const Operand&  rhs,
703                               Label* if_true,
704                               Label* if_false,
705                               Label* fall_through) {
706   if (if_false == fall_through) {
707     __ Branch(if_true, cc, lhs, rhs);
708   } else if (if_true == fall_through) {
709     __ Branch(if_false, NegateCondition(cc), lhs, rhs);
710   } else {
711     __ Branch(if_true, cc, lhs, rhs);
712     __ Branch(if_false);
713   }
714 }
715
716
717 MemOperand FullCodeGenerator::StackOperand(Variable* var) {
718   DCHECK(var->IsStackAllocated());
719   // Offset is negative because higher indexes are at lower addresses.
720   int offset = -var->index() * kPointerSize;
721   // Adjust by a (parameter or local) base offset.
722   if (var->IsParameter()) {
723     offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
724   } else {
725     offset += JavaScriptFrameConstants::kLocal0Offset;
726   }
727   return MemOperand(fp, offset);
728 }
729
730
731 MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) {
732   DCHECK(var->IsContextSlot() || var->IsStackAllocated());
733   if (var->IsContextSlot()) {
734     int context_chain_length = scope()->ContextChainLength(var->scope());
735     __ LoadContext(scratch, context_chain_length);
736     return ContextOperand(scratch, var->index());
737   } else {
738     return StackOperand(var);
739   }
740 }
741
742
743 void FullCodeGenerator::GetVar(Register dest, Variable* var) {
744   // Use destination as scratch.
745   MemOperand location = VarOperand(var, dest);
746   __ lw(dest, location);
747 }
748
749
750 void FullCodeGenerator::SetVar(Variable* var,
751                                Register src,
752                                Register scratch0,
753                                Register scratch1) {
754   DCHECK(var->IsContextSlot() || var->IsStackAllocated());
755   DCHECK(!scratch0.is(src));
756   DCHECK(!scratch0.is(scratch1));
757   DCHECK(!scratch1.is(src));
758   MemOperand location = VarOperand(var, scratch0);
759   __ sw(src, location);
760   // Emit the write barrier code if the location is in the heap.
761   if (var->IsContextSlot()) {
762     __ RecordWriteContextSlot(scratch0,
763                               location.offset(),
764                               src,
765                               scratch1,
766                               kRAHasBeenSaved,
767                               kDontSaveFPRegs);
768   }
769 }
770
771
772 void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
773                                                      bool should_normalize,
774                                                      Label* if_true,
775                                                      Label* if_false) {
776   // Only prepare for bailouts before splits if we're in a test
777   // context. Otherwise, we let the Visit function deal with the
778   // preparation to avoid preparing with the same AST id twice.
779   if (!context()->IsTest()) return;
780
781   Label skip;
782   if (should_normalize) __ Branch(&skip);
783   PrepareForBailout(expr, TOS_REG);
784   if (should_normalize) {
785     __ LoadRoot(t0, Heap::kTrueValueRootIndex);
786     Split(eq, a0, Operand(t0), if_true, if_false, NULL);
787     __ bind(&skip);
788   }
789 }
790
791
792 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
793   // The variable in the declaration always resides in the current function
794   // context.
795   DCHECK_EQ(0, scope()->ContextChainLength(variable->scope()));
796   if (generate_debug_code_) {
797     // Check that we're not inside a with or catch context.
798     __ lw(a1, FieldMemOperand(cp, HeapObject::kMapOffset));
799     __ LoadRoot(t0, Heap::kWithContextMapRootIndex);
800     __ Check(ne, kDeclarationInWithContext,
801         a1, Operand(t0));
802     __ LoadRoot(t0, Heap::kCatchContextMapRootIndex);
803     __ Check(ne, kDeclarationInCatchContext,
804         a1, Operand(t0));
805   }
806 }
807
808
809 void FullCodeGenerator::VisitVariableDeclaration(
810     VariableDeclaration* declaration) {
811   // If it was not possible to allocate the variable at compile time, we
812   // need to "declare" it at runtime to make sure it actually exists in the
813   // local context.
814   VariableProxy* proxy = declaration->proxy();
815   VariableMode mode = declaration->mode();
816   Variable* variable = proxy->var();
817   bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
818   switch (variable->location()) {
819     case VariableLocation::GLOBAL:
820     case VariableLocation::UNALLOCATED:
821       globals_->Add(variable->name(), zone());
822       globals_->Add(variable->binding_needs_init()
823                         ? isolate()->factory()->the_hole_value()
824                         : isolate()->factory()->undefined_value(),
825                     zone());
826       break;
827
828     case VariableLocation::PARAMETER:
829     case VariableLocation::LOCAL:
830       if (hole_init) {
831         Comment cmnt(masm_, "[ VariableDeclaration");
832         __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
833         __ sw(t0, StackOperand(variable));
834       }
835       break;
836
837     case VariableLocation::CONTEXT:
838       if (hole_init) {
839         Comment cmnt(masm_, "[ VariableDeclaration");
840         EmitDebugCheckDeclarationContext(variable);
841           __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
842           __ sw(at, ContextOperand(cp, variable->index()));
843           // No write barrier since the_hole_value is in old space.
844           PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
845       }
846       break;
847
848     case VariableLocation::LOOKUP: {
849       Comment cmnt(masm_, "[ VariableDeclaration");
850       __ li(a2, Operand(variable->name()));
851       // Declaration nodes are always introduced in one of four modes.
852       DCHECK(IsDeclaredVariableMode(mode));
853       // Push initial value, if any.
854       // Note: For variables we must not push an initial value (such as
855       // 'undefined') because we may have a (legal) redeclaration and we
856       // must not destroy the current value.
857       if (hole_init) {
858         __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
859       } else {
860         DCHECK(Smi::FromInt(0) == 0);
861         __ mov(a0, zero_reg);  // Smi::FromInt(0) indicates no initial value.
862       }
863       __ Push(a2, a0);
864       __ CallRuntime(IsImmutableVariableMode(mode)
865                          ? Runtime::kDeclareReadOnlyLookupSlot
866                          : Runtime::kDeclareLookupSlot,
867                      2);
868       break;
869     }
870   }
871 }
872
873
874 void FullCodeGenerator::VisitFunctionDeclaration(
875     FunctionDeclaration* declaration) {
876   VariableProxy* proxy = declaration->proxy();
877   Variable* variable = proxy->var();
878   switch (variable->location()) {
879     case VariableLocation::GLOBAL:
880     case VariableLocation::UNALLOCATED: {
881       globals_->Add(variable->name(), zone());
882       Handle<SharedFunctionInfo> function =
883           Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
884       // Check for stack-overflow exception.
885       if (function.is_null()) return SetStackOverflow();
886       globals_->Add(function, zone());
887       break;
888     }
889
890     case VariableLocation::PARAMETER:
891     case VariableLocation::LOCAL: {
892       Comment cmnt(masm_, "[ FunctionDeclaration");
893       VisitForAccumulatorValue(declaration->fun());
894       __ sw(result_register(), StackOperand(variable));
895       break;
896     }
897
898     case VariableLocation::CONTEXT: {
899       Comment cmnt(masm_, "[ FunctionDeclaration");
900       EmitDebugCheckDeclarationContext(variable);
901       VisitForAccumulatorValue(declaration->fun());
902       __ sw(result_register(), ContextOperand(cp, variable->index()));
903       int offset = Context::SlotOffset(variable->index());
904       // We know that we have written a function, which is not a smi.
905       __ RecordWriteContextSlot(cp,
906                                 offset,
907                                 result_register(),
908                                 a2,
909                                 kRAHasBeenSaved,
910                                 kDontSaveFPRegs,
911                                 EMIT_REMEMBERED_SET,
912                                 OMIT_SMI_CHECK);
913       PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
914       break;
915     }
916
917     case VariableLocation::LOOKUP: {
918       Comment cmnt(masm_, "[ FunctionDeclaration");
919       __ li(a2, Operand(variable->name()));
920       __ Push(a2);
921       // Push initial value for function declaration.
922       VisitForStackValue(declaration->fun());
923       __ CallRuntime(Runtime::kDeclareLookupSlot, 2);
924       break;
925     }
926   }
927 }
928
929
930 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
931   // Call the runtime to declare the globals.
932   __ li(a1, Operand(pairs));
933   __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
934   __ Push(a1, a0);
935   __ CallRuntime(Runtime::kDeclareGlobals, 2);
936   // Return value is ignored.
937 }
938
939
940 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
941   // Call the runtime to declare the modules.
942   __ Push(descriptions);
943   __ CallRuntime(Runtime::kDeclareModules, 1);
944   // Return value is ignored.
945 }
946
947
948 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
949   Comment cmnt(masm_, "[ SwitchStatement");
950   Breakable nested_statement(this, stmt);
951   SetStatementPosition(stmt);
952
953   // Keep the switch value on the stack until a case matches.
954   VisitForStackValue(stmt->tag());
955   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
956
957   ZoneList<CaseClause*>* clauses = stmt->cases();
958   CaseClause* default_clause = NULL;  // Can occur anywhere in the list.
959
960   Label next_test;  // Recycled for each test.
961   // Compile all the tests with branches to their bodies.
962   for (int i = 0; i < clauses->length(); i++) {
963     CaseClause* clause = clauses->at(i);
964     clause->body_target()->Unuse();
965
966     // The default is not a test, but remember it as final fall through.
967     if (clause->is_default()) {
968       default_clause = clause;
969       continue;
970     }
971
972     Comment cmnt(masm_, "[ Case comparison");
973     __ bind(&next_test);
974     next_test.Unuse();
975
976     // Compile the label expression.
977     VisitForAccumulatorValue(clause->label());
978     __ mov(a0, result_register());  // CompareStub requires args in a0, a1.
979
980     // Perform the comparison as if via '==='.
981     __ lw(a1, MemOperand(sp, 0));  // Switch value.
982     bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT);
983     JumpPatchSite patch_site(masm_);
984     if (inline_smi_code) {
985       Label slow_case;
986       __ or_(a2, a1, a0);
987       patch_site.EmitJumpIfNotSmi(a2, &slow_case);
988
989       __ Branch(&next_test, ne, a1, Operand(a0));
990       __ Drop(1);  // Switch value is no longer needed.
991       __ Branch(clause->body_target());
992
993       __ bind(&slow_case);
994     }
995
996     // Record position before stub call for type feedback.
997     SetExpressionPosition(clause);
998     Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
999                                              strength(language_mode())).code();
1000     CallIC(ic, clause->CompareId());
1001     patch_site.EmitPatchInfo();
1002
1003     Label skip;
1004     __ Branch(&skip);
1005     PrepareForBailout(clause, TOS_REG);
1006     __ LoadRoot(at, Heap::kTrueValueRootIndex);
1007     __ Branch(&next_test, ne, v0, Operand(at));
1008     __ Drop(1);
1009     __ Branch(clause->body_target());
1010     __ bind(&skip);
1011
1012     __ Branch(&next_test, ne, v0, Operand(zero_reg));
1013     __ Drop(1);  // Switch value is no longer needed.
1014     __ Branch(clause->body_target());
1015   }
1016
1017   // Discard the test value and jump to the default if present, otherwise to
1018   // the end of the statement.
1019   __ bind(&next_test);
1020   __ Drop(1);  // Switch value is no longer needed.
1021   if (default_clause == NULL) {
1022     __ Branch(nested_statement.break_label());
1023   } else {
1024     __ Branch(default_clause->body_target());
1025   }
1026
1027   // Compile all the case bodies.
1028   for (int i = 0; i < clauses->length(); i++) {
1029     Comment cmnt(masm_, "[ Case body");
1030     CaseClause* clause = clauses->at(i);
1031     __ bind(clause->body_target());
1032     PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
1033     VisitStatements(clause->statements());
1034   }
1035
1036   __ bind(nested_statement.break_label());
1037   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1038 }
1039
1040
1041 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1042   Comment cmnt(masm_, "[ ForInStatement");
1043   SetStatementPosition(stmt, SKIP_BREAK);
1044
1045   FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
1046
1047   Label loop, exit;
1048   ForIn loop_statement(this, stmt);
1049   increment_loop_depth();
1050
1051   // Get the object to enumerate over. If the object is null or undefined, skip
1052   // over the loop.  See ECMA-262 version 5, section 12.6.4.
1053   SetExpressionAsStatementPosition(stmt->enumerable());
1054   VisitForAccumulatorValue(stmt->enumerable());
1055   __ mov(a0, result_register());  // Result as param to InvokeBuiltin below.
1056   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1057   __ Branch(&exit, eq, a0, Operand(at));
1058   Register null_value = t1;
1059   __ LoadRoot(null_value, Heap::kNullValueRootIndex);
1060   __ Branch(&exit, eq, a0, Operand(null_value));
1061   PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
1062   __ mov(a0, v0);
1063   // Convert the object to a JS object.
1064   Label convert, done_convert;
1065   __ JumpIfSmi(a0, &convert);
1066   __ GetObjectType(a0, a1, a1);
1067   __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
1068   __ bind(&convert);
1069   ToObjectStub stub(isolate());
1070   __ CallStub(&stub);
1071   __ mov(a0, v0);
1072   __ bind(&done_convert);
1073   PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
1074   __ push(a0);
1075
1076   // Check for proxies.
1077   Label call_runtime;
1078   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1079   __ GetObjectType(a0, a1, a1);
1080   __ Branch(&call_runtime, le, a1, Operand(LAST_JS_PROXY_TYPE));
1081
1082   // Check cache validity in generated code. This is a fast case for
1083   // the JSObject::IsSimpleEnum cache validity checks. If we cannot
1084   // guarantee cache validity, call the runtime system to check cache
1085   // validity or get the property names in a fixed array.
1086   __ CheckEnumCache(null_value, &call_runtime);
1087
1088   // The enum cache is valid.  Load the map of the object being
1089   // iterated over and use the cache for the iteration.
1090   Label use_cache;
1091   __ lw(v0, FieldMemOperand(a0, HeapObject::kMapOffset));
1092   __ Branch(&use_cache);
1093
1094   // Get the set of properties to enumerate.
1095   __ bind(&call_runtime);
1096   __ push(a0);  // Duplicate the enumerable object on the stack.
1097   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
1098   PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1099
1100   // If we got a map from the runtime call, we can do a fast
1101   // modification check. Otherwise, we got a fixed array, and we have
1102   // to do a slow check.
1103   Label fixed_array;
1104   __ lw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
1105   __ LoadRoot(at, Heap::kMetaMapRootIndex);
1106   __ Branch(&fixed_array, ne, a2, Operand(at));
1107
1108   // We got a map in register v0. Get the enumeration cache from it.
1109   Label no_descriptors;
1110   __ bind(&use_cache);
1111
1112   __ EnumLength(a1, v0);
1113   __ Branch(&no_descriptors, eq, a1, Operand(Smi::FromInt(0)));
1114
1115   __ LoadInstanceDescriptors(v0, a2);
1116   __ lw(a2, FieldMemOperand(a2, DescriptorArray::kEnumCacheOffset));
1117   __ lw(a2, FieldMemOperand(a2, DescriptorArray::kEnumCacheBridgeCacheOffset));
1118
1119   // Set up the four remaining stack slots.
1120   __ li(a0, Operand(Smi::FromInt(0)));
1121   // Push map, enumeration cache, enumeration cache length (as smi) and zero.
1122   __ Push(v0, a2, a1, a0);
1123   __ jmp(&loop);
1124
1125   __ bind(&no_descriptors);
1126   __ Drop(1);
1127   __ jmp(&exit);
1128
1129   // We got a fixed array in register v0. Iterate through that.
1130   Label non_proxy;
1131   __ bind(&fixed_array);
1132
1133   __ li(a1, FeedbackVector());
1134   __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1135   int vector_index = FeedbackVector()->GetIndex(slot);
1136   __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(vector_index)));
1137
1138   __ li(a1, Operand(Smi::FromInt(1)));  // Smi indicates slow check
1139   __ lw(a2, MemOperand(sp, 0 * kPointerSize));  // Get enumerated object
1140   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1141   __ GetObjectType(a2, a3, a3);
1142   __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE));
1143   __ li(a1, Operand(Smi::FromInt(0)));  // Zero indicates proxy
1144   __ bind(&non_proxy);
1145   __ Push(a1, v0);  // Smi and array
1146   __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset));
1147   __ li(a0, Operand(Smi::FromInt(0)));
1148   __ Push(a1, a0);  // Fixed array length (as smi) and initial index.
1149
1150   // Generate code for doing the condition check.
1151   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1152   __ bind(&loop);
1153   SetExpressionAsStatementPosition(stmt->each());
1154
1155   // Load the current count to a0, load the length to a1.
1156   __ lw(a0, MemOperand(sp, 0 * kPointerSize));
1157   __ lw(a1, MemOperand(sp, 1 * kPointerSize));
1158   __ Branch(loop_statement.break_label(), hs, a0, Operand(a1));
1159
1160   // Get the current entry of the array into register a3.
1161   __ lw(a2, MemOperand(sp, 2 * kPointerSize));
1162   __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1163   __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize);
1164   __ addu(t0, a2, t0);  // Array base + scaled (smi) index.
1165   __ lw(a3, MemOperand(t0));  // Current entry.
1166
1167   // Get the expected map from the stack or a smi in the
1168   // permanent slow case into register a2.
1169   __ lw(a2, MemOperand(sp, 3 * kPointerSize));
1170
1171   // Check if the expected map still matches that of the enumerable.
1172   // If not, we may have to filter the key.
1173   Label update_each;
1174   __ lw(a1, MemOperand(sp, 4 * kPointerSize));
1175   __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset));
1176   __ Branch(&update_each, eq, t0, Operand(a2));
1177
1178   // For proxies, no filtering is done.
1179   // TODO(rossberg): What if only a prototype is a proxy? Not specified yet.
1180   DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0));
1181   __ Branch(&update_each, eq, a2, Operand(zero_reg));
1182
1183   // Convert the entry to a string or (smi) 0 if it isn't a property
1184   // any more. If the property has been removed while iterating, we
1185   // just skip it.
1186   __ Push(a1, a3);  // Enumerable and current entry.
1187   __ CallRuntime(Runtime::kForInFilter, 2);
1188   PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1189   __ mov(a3, result_register());
1190   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1191   __ Branch(loop_statement.continue_label(), eq, a3, Operand(at));
1192
1193   // Update the 'each' property or variable from the possibly filtered
1194   // entry in register a3.
1195   __ bind(&update_each);
1196   __ mov(result_register(), a3);
1197   // Perform the assignment as if via '='.
1198   { EffectContext context(this);
1199     EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1200     PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS);
1201   }
1202
1203   // Generate code for the body of the loop.
1204   Visit(stmt->body());
1205
1206   // Generate code for the going to the next element by incrementing
1207   // the index (smi) stored on top of the stack.
1208   __ bind(loop_statement.continue_label());
1209   __ pop(a0);
1210   __ Addu(a0, a0, Operand(Smi::FromInt(1)));
1211   __ push(a0);
1212
1213   EmitBackEdgeBookkeeping(stmt, &loop);
1214   __ Branch(&loop);
1215
1216   // Remove the pointers stored on the stack.
1217   __ bind(loop_statement.break_label());
1218   __ Drop(5);
1219
1220   // Exit and decrement the loop depth.
1221   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1222   __ bind(&exit);
1223   decrement_loop_depth();
1224 }
1225
1226
1227 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
1228                                        bool pretenure) {
1229   // Use the fast case closure allocation code that allocates in new
1230   // space for nested functions that don't need literals cloning. If
1231   // we're running with the --always-opt or the --prepare-always-opt
1232   // flag, we need to use the runtime function so that the new function
1233   // we are creating here gets a chance to have its code optimized and
1234   // doesn't just get a copy of the existing unoptimized code.
1235   if (!FLAG_always_opt &&
1236       !FLAG_prepare_always_opt &&
1237       !pretenure &&
1238       scope()->is_function_scope() &&
1239       info->num_literals() == 0) {
1240     FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
1241     __ li(a2, Operand(info));
1242     __ CallStub(&stub);
1243   } else {
1244     __ Push(info);
1245     __ CallRuntime(
1246         pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1);
1247   }
1248   context()->Plug(v0);
1249 }
1250
1251
1252 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1253                                           FeedbackVectorICSlot slot) {
1254   DCHECK(NeedsHomeObject(initializer));
1255   __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1256   __ li(StoreDescriptor::NameRegister(),
1257         Operand(isolate()->factory()->home_object_symbol()));
1258   __ lw(StoreDescriptor::ValueRegister(),
1259         MemOperand(sp, offset * kPointerSize));
1260   if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1261   CallStoreIC();
1262 }
1263
1264
1265 void FullCodeGenerator::EmitSetHomeObjectAccumulator(
1266     Expression* initializer, int offset, FeedbackVectorICSlot slot) {
1267   DCHECK(NeedsHomeObject(initializer));
1268   __ Move(StoreDescriptor::ReceiverRegister(), v0);
1269   __ li(StoreDescriptor::NameRegister(),
1270         Operand(isolate()->factory()->home_object_symbol()));
1271   __ lw(StoreDescriptor::ValueRegister(),
1272         MemOperand(sp, offset * kPointerSize));
1273   if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1274   CallStoreIC();
1275 }
1276
1277
1278 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1279                                                       TypeofMode typeof_mode,
1280                                                       Label* slow) {
1281   Register current = cp;
1282   Register next = a1;
1283   Register temp = a2;
1284
1285   Scope* s = scope();
1286   while (s != NULL) {
1287     if (s->num_heap_slots() > 0) {
1288       if (s->calls_sloppy_eval()) {
1289         // Check that extension is NULL.
1290         __ lw(temp, ContextOperand(current, Context::EXTENSION_INDEX));
1291         __ Branch(slow, ne, temp, Operand(zero_reg));
1292       }
1293       // Load next context in chain.
1294       __ lw(next, ContextOperand(current, Context::PREVIOUS_INDEX));
1295       // Walk the rest of the chain without clobbering cp.
1296       current = next;
1297     }
1298     // If no outer scope calls eval, we do not need to check more
1299     // context extensions.
1300     if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
1301     s = s->outer_scope();
1302   }
1303
1304   if (s->is_eval_scope()) {
1305     Label loop, fast;
1306     if (!current.is(next)) {
1307       __ Move(next, current);
1308     }
1309     __ bind(&loop);
1310     // Terminate at native context.
1311     __ lw(temp, FieldMemOperand(next, HeapObject::kMapOffset));
1312     __ LoadRoot(t0, Heap::kNativeContextMapRootIndex);
1313     __ Branch(&fast, eq, temp, Operand(t0));
1314     // Check that extension is NULL.
1315     __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX));
1316     __ Branch(slow, ne, temp, Operand(zero_reg));
1317     // Load next context in chain.
1318     __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX));
1319     __ Branch(&loop);
1320     __ bind(&fast);
1321   }
1322
1323   // All extension objects were empty and it is safe to use a normal global
1324   // load machinery.
1325   EmitGlobalVariableLoad(proxy, typeof_mode);
1326 }
1327
1328
1329 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1330                                                                 Label* slow) {
1331   DCHECK(var->IsContextSlot());
1332   Register context = cp;
1333   Register next = a3;
1334   Register temp = t0;
1335
1336   for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
1337     if (s->num_heap_slots() > 0) {
1338       if (s->calls_sloppy_eval()) {
1339         // Check that extension is NULL.
1340         __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX));
1341         __ Branch(slow, ne, temp, Operand(zero_reg));
1342       }
1343       __ lw(next, ContextOperand(context, Context::PREVIOUS_INDEX));
1344       // Walk the rest of the chain without clobbering cp.
1345       context = next;
1346     }
1347   }
1348   // Check that last extension is NULL.
1349   __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX));
1350   __ Branch(slow, ne, temp, Operand(zero_reg));
1351
1352   // This function is used only for loads, not stores, so it's safe to
1353   // return an cp-based operand (the write barrier cannot be allowed to
1354   // destroy the cp register).
1355   return ContextOperand(context, var->index());
1356 }
1357
1358
1359 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1360                                                   TypeofMode typeof_mode,
1361                                                   Label* slow, Label* done) {
1362   // Generate fast-case code for variables that might be shadowed by
1363   // eval-introduced variables.  Eval is used a lot without
1364   // introducing variables.  In those cases, we do not want to
1365   // perform a runtime call for all variables in the scope
1366   // containing the eval.
1367   Variable* var = proxy->var();
1368   if (var->mode() == DYNAMIC_GLOBAL) {
1369     EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1370     __ Branch(done);
1371   } else if (var->mode() == DYNAMIC_LOCAL) {
1372     Variable* local = var->local_if_not_shadowed();
1373     __ lw(v0, ContextSlotOperandCheckExtensions(local, slow));
1374     if (local->mode() == LET || local->mode() == CONST ||
1375         local->mode() == CONST_LEGACY) {
1376       __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1377       __ subu(at, v0, at);  // Sub as compare: at == 0 on eq.
1378       if (local->mode() == CONST_LEGACY) {
1379         __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1380         __ Movz(v0, a0, at);  // Conditional move: return Undefined if TheHole.
1381       } else {  // LET || CONST
1382         __ Branch(done, ne, at, Operand(zero_reg));
1383         __ li(a0, Operand(var->name()));
1384         __ push(a0);
1385         __ CallRuntime(Runtime::kThrowReferenceError, 1);
1386       }
1387     }
1388     __ Branch(done);
1389   }
1390 }
1391
1392
1393 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1394                                                TypeofMode typeof_mode) {
1395   Variable* var = proxy->var();
1396   DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1397          (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
1398   if (var->IsGlobalSlot()) {
1399     DCHECK(var->index() > 0);
1400     DCHECK(var->IsStaticGlobalObjectProperty());
1401     int const slot = var->index();
1402     int const depth = scope()->ContextChainLength(var->scope());
1403     if (depth <= LoadGlobalViaContextStub::kMaximumDepth) {
1404       __ li(LoadGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
1405       LoadGlobalViaContextStub stub(isolate(), depth);
1406       __ CallStub(&stub);
1407     } else {
1408       __ Push(Smi::FromInt(slot));
1409       __ CallRuntime(Runtime::kLoadGlobalViaContext, 1);
1410     }
1411
1412   } else {
1413     __ lw(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1414     __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
1415     __ li(LoadDescriptor::SlotRegister(),
1416           Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1417     CallLoadIC(typeof_mode);
1418   }
1419 }
1420
1421
1422 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1423                                          TypeofMode typeof_mode) {
1424   // Record position before possible IC call.
1425   SetExpressionPosition(proxy);
1426   PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1427   Variable* var = proxy->var();
1428
1429   // Three cases: global variables, lookup variables, and all other types of
1430   // variables.
1431   switch (var->location()) {
1432     case VariableLocation::GLOBAL:
1433     case VariableLocation::UNALLOCATED: {
1434       Comment cmnt(masm_, "[ Global variable");
1435       EmitGlobalVariableLoad(proxy, typeof_mode);
1436       context()->Plug(v0);
1437       break;
1438     }
1439
1440     case VariableLocation::PARAMETER:
1441     case VariableLocation::LOCAL:
1442     case VariableLocation::CONTEXT: {
1443       DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1444       Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1445                                                : "[ Stack variable");
1446       if (NeedsHoleCheckForLoad(proxy)) {
1447         // Let and const need a read barrier.
1448         GetVar(v0, var);
1449         __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1450         __ subu(at, v0, at);  // Sub as compare: at == 0 on eq.
1451         if (var->mode() == LET || var->mode() == CONST) {
1452           // Throw a reference error when using an uninitialized let/const
1453           // binding in harmony mode.
1454           Label done;
1455           __ Branch(&done, ne, at, Operand(zero_reg));
1456           __ li(a0, Operand(var->name()));
1457           __ push(a0);
1458           __ CallRuntime(Runtime::kThrowReferenceError, 1);
1459           __ bind(&done);
1460         } else {
1461           // Uninitialized legacy const bindings are unholed.
1462           DCHECK(var->mode() == CONST_LEGACY);
1463           __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1464           __ Movz(v0, a0, at);  // Conditional move: Undefined if TheHole.
1465         }
1466         context()->Plug(v0);
1467         break;
1468       }
1469       context()->Plug(var);
1470       break;
1471     }
1472
1473     case VariableLocation::LOOKUP: {
1474       Comment cmnt(masm_, "[ Lookup variable");
1475       Label done, slow;
1476       // Generate code for loading from variables potentially shadowed
1477       // by eval-introduced variables.
1478       EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1479       __ bind(&slow);
1480       __ li(a1, Operand(var->name()));
1481       __ Push(cp, a1);  // Context and name.
1482       Runtime::FunctionId function_id =
1483           typeof_mode == NOT_INSIDE_TYPEOF
1484               ? Runtime::kLoadLookupSlot
1485               : Runtime::kLoadLookupSlotNoReferenceError;
1486       __ CallRuntime(function_id, 2);
1487       __ bind(&done);
1488       context()->Plug(v0);
1489     }
1490   }
1491 }
1492
1493
1494 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1495   Comment cmnt(masm_, "[ RegExpLiteral");
1496   Label materialized;
1497   // Registers will be used as follows:
1498   // t1 = materialized value (RegExp literal)
1499   // t0 = JS function, literals array
1500   // a3 = literal index
1501   // a2 = RegExp pattern
1502   // a1 = RegExp flags
1503   // a0 = RegExp literal clone
1504   __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1505   __ lw(t0, FieldMemOperand(a0, JSFunction::kLiteralsOffset));
1506   int literal_offset =
1507       FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
1508   __ lw(t1, FieldMemOperand(t0, literal_offset));
1509   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1510   __ Branch(&materialized, ne, t1, Operand(at));
1511
1512   // Create regexp literal using runtime function.
1513   // Result will be in v0.
1514   __ li(a3, Operand(Smi::FromInt(expr->literal_index())));
1515   __ li(a2, Operand(expr->pattern()));
1516   __ li(a1, Operand(expr->flags()));
1517   __ Push(t0, a3, a2, a1);
1518   __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1519   __ mov(t1, v0);
1520
1521   __ bind(&materialized);
1522   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1523   Label allocated, runtime_allocate;
1524   __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
1525   __ jmp(&allocated);
1526
1527   __ bind(&runtime_allocate);
1528   __ li(a0, Operand(Smi::FromInt(size)));
1529   __ Push(t1, a0);
1530   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1531   __ pop(t1);
1532
1533   __ bind(&allocated);
1534
1535   // After this, registers are used as follows:
1536   // v0: Newly allocated regexp.
1537   // t1: Materialized regexp.
1538   // a2: temp.
1539   __ CopyFields(v0, t1, a2.bit(), size / kPointerSize);
1540   context()->Plug(v0);
1541 }
1542
1543
1544 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1545   Expression* expression = (property == NULL) ? NULL : property->value();
1546   if (expression == NULL) {
1547     __ LoadRoot(a1, Heap::kNullValueRootIndex);
1548     __ push(a1);
1549   } else {
1550     VisitForStackValue(expression);
1551     if (NeedsHomeObject(expression)) {
1552       DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1553              property->kind() == ObjectLiteral::Property::SETTER);
1554       int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1555       EmitSetHomeObject(expression, offset, property->GetSlot());
1556     }
1557   }
1558 }
1559
1560
1561 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1562   Comment cmnt(masm_, "[ ObjectLiteral");
1563
1564   Handle<FixedArray> constant_properties = expr->constant_properties();
1565   __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1566   __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
1567   __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1568   __ li(a1, Operand(constant_properties));
1569   __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags())));
1570   if (MustCreateObjectLiteralWithRuntime(expr)) {
1571     __ Push(a3, a2, a1, a0);
1572     __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
1573   } else {
1574     FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1575     __ CallStub(&stub);
1576   }
1577   PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1578
1579   // If result_saved is true the result is on top of the stack.  If
1580   // result_saved is false the result is in v0.
1581   bool result_saved = false;
1582
1583   AccessorTable accessor_table(zone());
1584   int property_index = 0;
1585   for (; property_index < expr->properties()->length(); property_index++) {
1586     ObjectLiteral::Property* property = expr->properties()->at(property_index);
1587     if (property->is_computed_name()) break;
1588     if (property->IsCompileTimeValue()) continue;
1589
1590     Literal* key = property->key()->AsLiteral();
1591     Expression* value = property->value();
1592     if (!result_saved) {
1593       __ push(v0);  // Save result on stack.
1594       result_saved = true;
1595     }
1596     switch (property->kind()) {
1597       case ObjectLiteral::Property::CONSTANT:
1598         UNREACHABLE();
1599       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1600         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1601         // Fall through.
1602       case ObjectLiteral::Property::COMPUTED:
1603         // It is safe to use [[Put]] here because the boilerplate already
1604         // contains computed properties with an uninitialized value.
1605         if (key->value()->IsInternalizedString()) {
1606           if (property->emit_store()) {
1607             VisitForAccumulatorValue(value);
1608             __ mov(StoreDescriptor::ValueRegister(), result_register());
1609             DCHECK(StoreDescriptor::ValueRegister().is(a0));
1610             __ li(StoreDescriptor::NameRegister(), Operand(key->value()));
1611             __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1612             if (FLAG_vector_stores) {
1613               EmitLoadStoreICSlot(property->GetSlot(0));
1614               CallStoreIC();
1615             } else {
1616               CallStoreIC(key->LiteralFeedbackId());
1617             }
1618             PrepareForBailoutForId(key->id(), NO_REGISTERS);
1619
1620             if (NeedsHomeObject(value)) {
1621               EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1622             }
1623           } else {
1624             VisitForEffect(value);
1625           }
1626           break;
1627         }
1628         // Duplicate receiver on stack.
1629         __ lw(a0, MemOperand(sp));
1630         __ push(a0);
1631         VisitForStackValue(key);
1632         VisitForStackValue(value);
1633         if (property->emit_store()) {
1634           if (NeedsHomeObject(value)) {
1635             EmitSetHomeObject(value, 2, property->GetSlot());
1636           }
1637           __ li(a0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes.
1638           __ push(a0);
1639           __ CallRuntime(Runtime::kSetProperty, 4);
1640         } else {
1641           __ Drop(3);
1642         }
1643         break;
1644       case ObjectLiteral::Property::PROTOTYPE:
1645         // Duplicate receiver on stack.
1646         __ lw(a0, MemOperand(sp));
1647         __ push(a0);
1648         VisitForStackValue(value);
1649         DCHECK(property->emit_store());
1650         __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1651         break;
1652       case ObjectLiteral::Property::GETTER:
1653         if (property->emit_store()) {
1654           accessor_table.lookup(key)->second->getter = property;
1655         }
1656         break;
1657       case ObjectLiteral::Property::SETTER:
1658         if (property->emit_store()) {
1659           accessor_table.lookup(key)->second->setter = property;
1660         }
1661         break;
1662     }
1663   }
1664
1665   // Emit code to define accessors, using only a single call to the runtime for
1666   // each pair of corresponding getters and setters.
1667   for (AccessorTable::Iterator it = accessor_table.begin();
1668        it != accessor_table.end();
1669        ++it) {
1670     __ lw(a0, MemOperand(sp));  // Duplicate receiver.
1671     __ push(a0);
1672     VisitForStackValue(it->first);
1673     EmitAccessor(it->second->getter);
1674     EmitAccessor(it->second->setter);
1675     __ li(a0, Operand(Smi::FromInt(NONE)));
1676     __ push(a0);
1677     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1678   }
1679
1680   // Object literals have two parts. The "static" part on the left contains no
1681   // computed property names, and so we can compute its map ahead of time; see
1682   // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1683   // starts with the first computed property name, and continues with all
1684   // properties to its right.  All the code from above initializes the static
1685   // component of the object literal, and arranges for the map of the result to
1686   // reflect the static order in which the keys appear. For the dynamic
1687   // properties, we compile them into a series of "SetOwnProperty" runtime
1688   // calls. This will preserve insertion order.
1689   for (; property_index < expr->properties()->length(); property_index++) {
1690     ObjectLiteral::Property* property = expr->properties()->at(property_index);
1691
1692     Expression* value = property->value();
1693     if (!result_saved) {
1694       __ push(v0);  // Save result on the stack
1695       result_saved = true;
1696     }
1697
1698     __ lw(a0, MemOperand(sp));  // Duplicate receiver.
1699     __ push(a0);
1700
1701     if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1702       DCHECK(!property->is_computed_name());
1703       VisitForStackValue(value);
1704       DCHECK(property->emit_store());
1705       __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1706     } else {
1707       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1708       VisitForStackValue(value);
1709       if (NeedsHomeObject(value)) {
1710         EmitSetHomeObject(value, 2, property->GetSlot());
1711       }
1712
1713       switch (property->kind()) {
1714         case ObjectLiteral::Property::CONSTANT:
1715         case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1716         case ObjectLiteral::Property::COMPUTED:
1717           if (property->emit_store()) {
1718             __ li(a0, Operand(Smi::FromInt(NONE)));
1719             __ push(a0);
1720             __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1721           } else {
1722             __ Drop(3);
1723           }
1724           break;
1725
1726         case ObjectLiteral::Property::PROTOTYPE:
1727           UNREACHABLE();
1728           break;
1729
1730         case ObjectLiteral::Property::GETTER:
1731           __ li(a0, Operand(Smi::FromInt(NONE)));
1732           __ push(a0);
1733           __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4);
1734           break;
1735
1736         case ObjectLiteral::Property::SETTER:
1737           __ li(a0, Operand(Smi::FromInt(NONE)));
1738           __ push(a0);
1739           __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4);
1740           break;
1741       }
1742     }
1743   }
1744
1745   if (expr->has_function()) {
1746     DCHECK(result_saved);
1747     __ lw(a0, MemOperand(sp));
1748     __ push(a0);
1749     __ CallRuntime(Runtime::kToFastProperties, 1);
1750   }
1751
1752   if (result_saved) {
1753     context()->PlugTOS();
1754   } else {
1755     context()->Plug(v0);
1756   }
1757 }
1758
1759
1760 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1761   Comment cmnt(masm_, "[ ArrayLiteral");
1762
1763   expr->BuildConstantElements(isolate());
1764
1765   Handle<FixedArray> constant_elements = expr->constant_elements();
1766   bool has_fast_elements =
1767       IsFastObjectElementsKind(expr->constant_elements_kind());
1768
1769   AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
1770   if (has_fast_elements && !FLAG_allocation_site_pretenuring) {
1771     // If the only customer of allocation sites is transitioning, then
1772     // we can turn it off if we don't have anywhere else to transition to.
1773     allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1774   }
1775
1776   __ mov(a0, result_register());
1777   __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1778   __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
1779   __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1780   __ li(a1, Operand(constant_elements));
1781   if (MustCreateArrayLiteralWithRuntime(expr)) {
1782     __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags())));
1783     __ Push(a3, a2, a1, a0);
1784     __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
1785   } else {
1786     FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1787     __ CallStub(&stub);
1788   }
1789   PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1790
1791   bool result_saved = false;  // Is the result saved to the stack?
1792   ZoneList<Expression*>* subexprs = expr->values();
1793   int length = subexprs->length();
1794
1795   // Emit code to evaluate all the non-constant subexpressions and to store
1796   // them into the newly cloned array.
1797   int array_index = 0;
1798   for (; array_index < length; array_index++) {
1799     Expression* subexpr = subexprs->at(array_index);
1800     if (subexpr->IsSpread()) break;
1801
1802     // If the subexpression is a literal or a simple materialized literal it
1803     // is already set in the cloned array.
1804     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1805
1806     if (!result_saved) {
1807       __ push(v0);  // array literal
1808       __ Push(Smi::FromInt(expr->literal_index()));
1809       result_saved = true;
1810     }
1811
1812     VisitForAccumulatorValue(subexpr);
1813
1814     if (has_fast_elements) {
1815       int offset = FixedArray::kHeaderSize + (array_index * kPointerSize);
1816       __ lw(t2, MemOperand(sp, kPointerSize));  // Copy of array literal.
1817       __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset));
1818       __ sw(result_register(), FieldMemOperand(a1, offset));
1819       // Update the write barrier for the array store.
1820       __ RecordWriteField(a1, offset, result_register(), a2,
1821                           kRAHasBeenSaved, kDontSaveFPRegs,
1822                           EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
1823     } else {
1824       __ li(a3, Operand(Smi::FromInt(array_index)));
1825       __ mov(a0, result_register());
1826       StoreArrayLiteralElementStub stub(isolate());
1827       __ CallStub(&stub);
1828     }
1829
1830     PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1831   }
1832
1833   // In case the array literal contains spread expressions it has two parts. The
1834   // first part is  the "static" array which has a literal index is  handled
1835   // above. The second part is the part after the first spread expression
1836   // (inclusive) and these elements gets appended to the array. Note that the
1837   // number elements an iterable produces is unknown ahead of time.
1838   if (array_index < length && result_saved) {
1839     __ Pop();  // literal index
1840     __ Pop(v0);
1841     result_saved = false;
1842   }
1843   for (; array_index < length; array_index++) {
1844     Expression* subexpr = subexprs->at(array_index);
1845
1846     __ Push(v0);
1847     if (subexpr->IsSpread()) {
1848       VisitForStackValue(subexpr->AsSpread()->expression());
1849       __ InvokeBuiltin(Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX,
1850                        CALL_FUNCTION);
1851     } else {
1852       VisitForStackValue(subexpr);
1853       __ CallRuntime(Runtime::kAppendElement, 2);
1854     }
1855
1856     PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1857   }
1858
1859   if (result_saved) {
1860     __ Pop();  // literal index
1861     context()->PlugTOS();
1862   } else {
1863     context()->Plug(v0);
1864   }
1865 }
1866
1867
1868 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1869   DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
1870
1871   Comment cmnt(masm_, "[ Assignment");
1872   SetExpressionPosition(expr, INSERT_BREAK);
1873
1874   Property* property = expr->target()->AsProperty();
1875   LhsKind assign_type = Property::GetAssignType(property);
1876
1877   // Evaluate LHS expression.
1878   switch (assign_type) {
1879     case VARIABLE:
1880       // Nothing to do here.
1881       break;
1882     case NAMED_PROPERTY:
1883       if (expr->is_compound()) {
1884         // We need the receiver both on the stack and in the register.
1885         VisitForStackValue(property->obj());
1886         __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1887       } else {
1888         VisitForStackValue(property->obj());
1889       }
1890       break;
1891     case NAMED_SUPER_PROPERTY:
1892       VisitForStackValue(
1893           property->obj()->AsSuperPropertyReference()->this_var());
1894       VisitForAccumulatorValue(
1895           property->obj()->AsSuperPropertyReference()->home_object());
1896       __ Push(result_register());
1897       if (expr->is_compound()) {
1898         const Register scratch = a1;
1899         __ lw(scratch, MemOperand(sp, kPointerSize));
1900         __ Push(scratch, result_register());
1901       }
1902       break;
1903     case KEYED_SUPER_PROPERTY: {
1904       const Register scratch = a1;
1905       VisitForStackValue(
1906           property->obj()->AsSuperPropertyReference()->this_var());
1907       VisitForAccumulatorValue(
1908           property->obj()->AsSuperPropertyReference()->home_object());
1909       __ Move(scratch, result_register());
1910       VisitForAccumulatorValue(property->key());
1911       __ Push(scratch, result_register());
1912       if (expr->is_compound()) {
1913         const Register scratch1 = t0;
1914         __ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
1915         __ Push(scratch1, scratch, result_register());
1916       }
1917       break;
1918     }
1919     case KEYED_PROPERTY:
1920       // We need the key and receiver on both the stack and in v0 and a1.
1921       if (expr->is_compound()) {
1922         VisitForStackValue(property->obj());
1923         VisitForStackValue(property->key());
1924         __ lw(LoadDescriptor::ReceiverRegister(),
1925               MemOperand(sp, 1 * kPointerSize));
1926         __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
1927       } else {
1928         VisitForStackValue(property->obj());
1929         VisitForStackValue(property->key());
1930       }
1931       break;
1932   }
1933
1934   // For compound assignments we need another deoptimization point after the
1935   // variable/property load.
1936   if (expr->is_compound()) {
1937     { AccumulatorValueContext context(this);
1938       switch (assign_type) {
1939         case VARIABLE:
1940           EmitVariableLoad(expr->target()->AsVariableProxy());
1941           PrepareForBailout(expr->target(), TOS_REG);
1942           break;
1943         case NAMED_PROPERTY:
1944           EmitNamedPropertyLoad(property);
1945           PrepareForBailoutForId(property->LoadId(), TOS_REG);
1946           break;
1947         case NAMED_SUPER_PROPERTY:
1948           EmitNamedSuperPropertyLoad(property);
1949           PrepareForBailoutForId(property->LoadId(), TOS_REG);
1950           break;
1951         case KEYED_SUPER_PROPERTY:
1952           EmitKeyedSuperPropertyLoad(property);
1953           PrepareForBailoutForId(property->LoadId(), TOS_REG);
1954           break;
1955         case KEYED_PROPERTY:
1956           EmitKeyedPropertyLoad(property);
1957           PrepareForBailoutForId(property->LoadId(), TOS_REG);
1958           break;
1959       }
1960     }
1961
1962     Token::Value op = expr->binary_op();
1963     __ push(v0);  // Left operand goes on the stack.
1964     VisitForAccumulatorValue(expr->value());
1965
1966     AccumulatorValueContext context(this);
1967     if (ShouldInlineSmiCase(op)) {
1968       EmitInlineSmiBinaryOp(expr->binary_operation(),
1969                             op,
1970                             expr->target(),
1971                             expr->value());
1972     } else {
1973       EmitBinaryOp(expr->binary_operation(), op);
1974     }
1975
1976     // Deoptimization point in case the binary operation may have side effects.
1977     PrepareForBailout(expr->binary_operation(), TOS_REG);
1978   } else {
1979     VisitForAccumulatorValue(expr->value());
1980   }
1981
1982   SetExpressionPosition(expr);
1983
1984   // Store the value.
1985   switch (assign_type) {
1986     case VARIABLE:
1987       EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1988                              expr->op(), expr->AssignmentSlot());
1989       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1990       context()->Plug(v0);
1991       break;
1992     case NAMED_PROPERTY:
1993       EmitNamedPropertyAssignment(expr);
1994       break;
1995     case NAMED_SUPER_PROPERTY:
1996       EmitNamedSuperPropertyStore(property);
1997       context()->Plug(v0);
1998       break;
1999     case KEYED_SUPER_PROPERTY:
2000       EmitKeyedSuperPropertyStore(property);
2001       context()->Plug(v0);
2002       break;
2003     case KEYED_PROPERTY:
2004       EmitKeyedPropertyAssignment(expr);
2005       break;
2006   }
2007 }
2008
2009
2010 void FullCodeGenerator::VisitYield(Yield* expr) {
2011   Comment cmnt(masm_, "[ Yield");
2012   SetExpressionPosition(expr);
2013
2014   // Evaluate yielded value first; the initial iterator definition depends on
2015   // this.  It stays on the stack while we update the iterator.
2016   VisitForStackValue(expr->expression());
2017
2018   switch (expr->yield_kind()) {
2019     case Yield::kSuspend:
2020       // Pop value from top-of-stack slot; box result into result register.
2021       EmitCreateIteratorResult(false);
2022       __ push(result_register());
2023       // Fall through.
2024     case Yield::kInitial: {
2025       Label suspend, continuation, post_runtime, resume;
2026
2027       __ jmp(&suspend);
2028       __ bind(&continuation);
2029       __ RecordGeneratorContinuation();
2030       __ jmp(&resume);
2031
2032       __ bind(&suspend);
2033       VisitForAccumulatorValue(expr->generator_object());
2034       DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
2035       __ li(a1, Operand(Smi::FromInt(continuation.pos())));
2036       __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset));
2037       __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
2038       __ mov(a1, cp);
2039       __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
2040                           kRAHasBeenSaved, kDontSaveFPRegs);
2041       __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
2042       __ Branch(&post_runtime, eq, sp, Operand(a1));
2043       __ push(v0);  // generator object
2044       __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2045       __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2046       __ bind(&post_runtime);
2047       __ pop(result_register());
2048       EmitReturnSequence();
2049
2050       __ bind(&resume);
2051       context()->Plug(result_register());
2052       break;
2053     }
2054
2055     case Yield::kFinal: {
2056       VisitForAccumulatorValue(expr->generator_object());
2057       __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
2058       __ sw(a1, FieldMemOperand(result_register(),
2059                                 JSGeneratorObject::kContinuationOffset));
2060       // Pop value from top-of-stack slot, box result into result register.
2061       EmitCreateIteratorResult(true);
2062       EmitUnwindBeforeReturn();
2063       EmitReturnSequence();
2064       break;
2065     }
2066
2067     case Yield::kDelegating: {
2068       VisitForStackValue(expr->generator_object());
2069
2070       // Initial stack layout is as follows:
2071       // [sp + 1 * kPointerSize] iter
2072       // [sp + 0 * kPointerSize] g
2073
2074       Label l_catch, l_try, l_suspend, l_continuation, l_resume;
2075       Label l_next, l_call;
2076       Register load_receiver = LoadDescriptor::ReceiverRegister();
2077       Register load_name = LoadDescriptor::NameRegister();
2078
2079       // Initial send value is undefined.
2080       __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
2081       __ Branch(&l_next);
2082
2083       // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2084       __ bind(&l_catch);
2085       __ mov(a0, v0);
2086       __ LoadRoot(load_name, Heap::kthrow_stringRootIndex);  // "throw"
2087       __ lw(a3, MemOperand(sp, 1 * kPointerSize));           // iter
2088       __ Push(load_name, a3, a0);                     // "throw", iter, except
2089       __ jmp(&l_call);
2090
2091       // try { received = %yield result }
2092       // Shuffle the received result above a try handler and yield it without
2093       // re-boxing.
2094       __ bind(&l_try);
2095       __ pop(a0);                                        // result
2096       int handler_index = NewHandlerTableEntry();
2097       EnterTryBlock(handler_index, &l_catch);
2098       const int try_block_size = TryCatch::kElementCount * kPointerSize;
2099       __ push(a0);                                       // result
2100
2101       __ jmp(&l_suspend);
2102       __ bind(&l_continuation);
2103       __ RecordGeneratorContinuation();
2104       __ mov(a0, v0);
2105       __ jmp(&l_resume);
2106
2107       __ bind(&l_suspend);
2108       const int generator_object_depth = kPointerSize + try_block_size;
2109       __ lw(a0, MemOperand(sp, generator_object_depth));
2110       __ push(a0);                                       // g
2111       __ Push(Smi::FromInt(handler_index));              // handler-index
2112       DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
2113       __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
2114       __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
2115       __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset));
2116       __ mov(a1, cp);
2117       __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2,
2118                           kRAHasBeenSaved, kDontSaveFPRegs);
2119       __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 2);
2120       __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2121       __ pop(v0);                                      // result
2122       EmitReturnSequence();
2123       __ mov(a0, v0);
2124       __ bind(&l_resume);                              // received in a0
2125       ExitTryBlock(handler_index);
2126
2127       // receiver = iter; f = 'next'; arg = received;
2128       __ bind(&l_next);
2129
2130       __ LoadRoot(load_name, Heap::knext_stringRootIndex);  // "next"
2131       __ lw(a3, MemOperand(sp, 1 * kPointerSize));          // iter
2132       __ Push(load_name, a3, a0);                      // "next", iter, received
2133
2134       // result = receiver[f](arg);
2135       __ bind(&l_call);
2136       __ lw(load_receiver, MemOperand(sp, kPointerSize));
2137       __ lw(load_name, MemOperand(sp, 2 * kPointerSize));
2138       __ li(LoadDescriptor::SlotRegister(),
2139             Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
2140       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code();
2141       CallIC(ic, TypeFeedbackId::None());
2142       __ mov(a0, v0);
2143       __ mov(a1, a0);
2144       __ sw(a1, MemOperand(sp, 2 * kPointerSize));
2145       SetCallPosition(expr, 1);
2146       CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2147       __ CallStub(&stub);
2148
2149       __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2150       __ Drop(1);  // The function is still on the stack; drop it.
2151
2152       // if (!result.done) goto l_try;
2153       __ Move(load_receiver, v0);
2154
2155       __ push(load_receiver);                               // save result
2156       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
2157       __ li(LoadDescriptor::SlotRegister(),
2158             Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
2159       CallLoadIC(NOT_INSIDE_TYPEOF);  // v0=result.done
2160       __ mov(a0, v0);
2161       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2162       CallIC(bool_ic);
2163       __ Branch(&l_try, eq, v0, Operand(zero_reg));
2164
2165       // result.value
2166       __ pop(load_receiver);                                 // result
2167       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
2168       __ li(LoadDescriptor::SlotRegister(),
2169             Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
2170       CallLoadIC(NOT_INSIDE_TYPEOF);                         // v0=result.value
2171       context()->DropAndPlug(2, v0);                         // drop iter and g
2172       break;
2173     }
2174   }
2175 }
2176
2177
2178 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2179     Expression *value,
2180     JSGeneratorObject::ResumeMode resume_mode) {
2181   // The value stays in a0, and is ultimately read by the resumed generator, as
2182   // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
2183   // is read to throw the value when the resumed generator is already closed.
2184   // a1 will hold the generator object until the activation has been resumed.
2185   VisitForStackValue(generator);
2186   VisitForAccumulatorValue(value);
2187   __ pop(a1);
2188
2189   // Load suspended function and context.
2190   __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
2191   __ lw(t0, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
2192
2193   // Load receiver and store as the first argument.
2194   __ lw(a2, FieldMemOperand(a1, JSGeneratorObject::kReceiverOffset));
2195   __ push(a2);
2196
2197   // Push holes for the rest of the arguments to the generator function.
2198   __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
2199   __ lw(a3,
2200         FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset));
2201   __ LoadRoot(a2, Heap::kTheHoleValueRootIndex);
2202   Label push_argument_holes, push_frame;
2203   __ bind(&push_argument_holes);
2204   __ Subu(a3, a3, Operand(Smi::FromInt(1)));
2205   __ Branch(&push_frame, lt, a3, Operand(zero_reg));
2206   __ push(a2);
2207   __ jmp(&push_argument_holes);
2208
2209   // Enter a new JavaScript frame, and initialize its slots as they were when
2210   // the generator was suspended.
2211   Label resume_frame, done;
2212   __ bind(&push_frame);
2213   __ Call(&resume_frame);
2214   __ jmp(&done);
2215   __ bind(&resume_frame);
2216   // ra = return address.
2217   // fp = caller's frame pointer.
2218   // cp = callee's context,
2219   // t0 = callee's JS function.
2220   __ Push(ra, fp, cp, t0);
2221   // Adjust FP to point to saved FP.
2222   __ Addu(fp, sp, 2 * kPointerSize);
2223
2224   // Load the operand stack size.
2225   __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset));
2226   __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset));
2227   __ SmiUntag(a3);
2228
2229   // If we are sending a value and there is no operand stack, we can jump back
2230   // in directly.
2231   if (resume_mode == JSGeneratorObject::NEXT) {
2232     Label slow_resume;
2233     __ Branch(&slow_resume, ne, a3, Operand(zero_reg));
2234     __ lw(a3, FieldMemOperand(t0, JSFunction::kCodeEntryOffset));
2235     __ lw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset));
2236     __ SmiUntag(a2);
2237     __ Addu(a3, a3, Operand(a2));
2238     __ li(a2, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
2239     __ sw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset));
2240     __ Jump(a3);
2241     __ bind(&slow_resume);
2242   }
2243
2244   // Otherwise, we push holes for the operand stack and call the runtime to fix
2245   // up the stack and the handlers.
2246   Label push_operand_holes, call_resume;
2247   __ bind(&push_operand_holes);
2248   __ Subu(a3, a3, Operand(1));
2249   __ Branch(&call_resume, lt, a3, Operand(zero_reg));
2250   __ push(a2);
2251   __ Branch(&push_operand_holes);
2252   __ bind(&call_resume);
2253   DCHECK(!result_register().is(a1));
2254   __ Push(a1, result_register());
2255   __ Push(Smi::FromInt(resume_mode));
2256   __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2257   // Not reached: the runtime call returns elsewhere.
2258   __ stop("not-reached");
2259
2260   __ bind(&done);
2261   context()->Plug(result_register());
2262 }
2263
2264
2265 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2266   Label allocate, done_allocate;
2267
2268   __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
2269   __ jmp(&done_allocate);
2270
2271   __ bind(&allocate);
2272   __ Push(Smi::FromInt(JSIteratorResult::kSize));
2273   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2274
2275   __ bind(&done_allocate);
2276   __ lw(a1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
2277   __ lw(a1, FieldMemOperand(a1, GlobalObject::kNativeContextOffset));
2278   __ lw(a1, ContextOperand(a1, Context::ITERATOR_RESULT_MAP_INDEX));
2279   __ pop(a2);
2280   __ LoadRoot(a3,
2281               done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
2282   __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex);
2283   __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
2284   __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset));
2285   __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
2286   __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset));
2287   __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset));
2288   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
2289 }
2290
2291
2292 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2293   SetExpressionPosition(prop);
2294   Literal* key = prop->key()->AsLiteral();
2295   DCHECK(!prop->IsSuperAccess());
2296
2297   __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
2298   __ li(LoadDescriptor::SlotRegister(),
2299         Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2300   CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
2301 }
2302
2303
2304 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2305   // Stack: receiver, home_object.
2306   SetExpressionPosition(prop);
2307
2308   Literal* key = prop->key()->AsLiteral();
2309   DCHECK(!key->value()->IsSmi());
2310   DCHECK(prop->IsSuperAccess());
2311
2312   __ Push(key->value());
2313   __ Push(Smi::FromInt(language_mode()));
2314   __ CallRuntime(Runtime::kLoadFromSuper, 4);
2315 }
2316
2317
2318 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2319   SetExpressionPosition(prop);
2320   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
2321   __ li(LoadDescriptor::SlotRegister(),
2322         Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
2323   CallIC(ic);
2324 }
2325
2326
2327 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
2328   // Stack: receiver, home_object, key.
2329   SetExpressionPosition(prop);
2330   __ Push(Smi::FromInt(language_mode()));
2331   __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
2332 }
2333
2334
2335 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2336                                               Token::Value op,
2337                                               Expression* left_expr,
2338                                               Expression* right_expr) {
2339   Label done, smi_case, stub_call;
2340
2341   Register scratch1 = a2;
2342   Register scratch2 = a3;
2343
2344   // Get the arguments.
2345   Register left = a1;
2346   Register right = a0;
2347   __ pop(left);
2348   __ mov(a0, result_register());
2349
2350   // Perform combined smi check on both operands.
2351   __ Or(scratch1, left, Operand(right));
2352   STATIC_ASSERT(kSmiTag == 0);
2353   JumpPatchSite patch_site(masm_);
2354   patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2355
2356   __ bind(&stub_call);
2357   Handle<Code> code =
2358       CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
2359   CallIC(code, expr->BinaryOperationFeedbackId());
2360   patch_site.EmitPatchInfo();
2361   __ jmp(&done);
2362
2363   __ bind(&smi_case);
2364   // Smi case. This code works the same way as the smi-smi case in the type
2365   // recording binary operation stub, see
2366   switch (op) {
2367     case Token::SAR:
2368       __ GetLeastBitsFromSmi(scratch1, right, 5);
2369       __ srav(right, left, scratch1);
2370       __ And(v0, right, Operand(~kSmiTagMask));
2371       break;
2372     case Token::SHL: {
2373       __ SmiUntag(scratch1, left);
2374       __ GetLeastBitsFromSmi(scratch2, right, 5);
2375       __ sllv(scratch1, scratch1, scratch2);
2376       __ Addu(scratch2, scratch1, Operand(0x40000000));
2377       __ Branch(&stub_call, lt, scratch2, Operand(zero_reg));
2378       __ SmiTag(v0, scratch1);
2379       break;
2380     }
2381     case Token::SHR: {
2382       __ SmiUntag(scratch1, left);
2383       __ GetLeastBitsFromSmi(scratch2, right, 5);
2384       __ srlv(scratch1, scratch1, scratch2);
2385       __ And(scratch2, scratch1, 0xc0000000);
2386       __ Branch(&stub_call, ne, scratch2, Operand(zero_reg));
2387       __ SmiTag(v0, scratch1);
2388       break;
2389     }
2390     case Token::ADD:
2391       __ AdduAndCheckForOverflow(v0, left, right, scratch1);
2392       __ BranchOnOverflow(&stub_call, scratch1);
2393       break;
2394     case Token::SUB:
2395       __ SubuAndCheckForOverflow(v0, left, right, scratch1);
2396       __ BranchOnOverflow(&stub_call, scratch1);
2397       break;
2398     case Token::MUL: {
2399       __ SmiUntag(scratch1, right);
2400       __ Mul(scratch2, v0, left, scratch1);
2401       __ sra(scratch1, v0, 31);
2402       __ Branch(&stub_call, ne, scratch1, Operand(scratch2));
2403       __ Branch(&done, ne, v0, Operand(zero_reg));
2404       __ Addu(scratch2, right, left);
2405       __ Branch(&stub_call, lt, scratch2, Operand(zero_reg));
2406       DCHECK(Smi::FromInt(0) == 0);
2407       __ mov(v0, zero_reg);
2408       break;
2409     }
2410     case Token::BIT_OR:
2411       __ Or(v0, left, Operand(right));
2412       break;
2413     case Token::BIT_AND:
2414       __ And(v0, left, Operand(right));
2415       break;
2416     case Token::BIT_XOR:
2417       __ Xor(v0, left, Operand(right));
2418       break;
2419     default:
2420       UNREACHABLE();
2421   }
2422
2423   __ bind(&done);
2424   context()->Plug(v0);
2425 }
2426
2427
2428 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2429   // Constructor is in v0.
2430   DCHECK(lit != NULL);
2431   __ push(v0);
2432
2433   // No access check is needed here since the constructor is created by the
2434   // class literal.
2435   Register scratch = a1;
2436   __ lw(scratch,
2437         FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
2438   __ push(scratch);
2439
2440   for (int i = 0; i < lit->properties()->length(); i++) {
2441     ObjectLiteral::Property* property = lit->properties()->at(i);
2442     Expression* value = property->value();
2443
2444     if (property->is_static()) {
2445       __ lw(scratch, MemOperand(sp, kPointerSize));  // constructor
2446     } else {
2447       __ lw(scratch, MemOperand(sp, 0));  // prototype
2448     }
2449     __ push(scratch);
2450     EmitPropertyKey(property, lit->GetIdForProperty(i));
2451
2452     // The static prototype property is read only. We handle the non computed
2453     // property name case in the parser. Since this is the only case where we
2454     // need to check for an own read only property we special case this so we do
2455     // not need to do this for every property.
2456     if (property->is_static() && property->is_computed_name()) {
2457       __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1);
2458       __ push(v0);
2459     }
2460
2461     VisitForStackValue(value);
2462     if (NeedsHomeObject(value)) {
2463       EmitSetHomeObject(value, 2, property->GetSlot());
2464     }
2465
2466     switch (property->kind()) {
2467       case ObjectLiteral::Property::CONSTANT:
2468       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2469       case ObjectLiteral::Property::PROTOTYPE:
2470         UNREACHABLE();
2471       case ObjectLiteral::Property::COMPUTED:
2472         __ CallRuntime(Runtime::kDefineClassMethod, 3);
2473         break;
2474
2475       case ObjectLiteral::Property::GETTER:
2476         __ li(a0, Operand(Smi::FromInt(DONT_ENUM)));
2477         __ push(a0);
2478         __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4);
2479         break;
2480
2481       case ObjectLiteral::Property::SETTER:
2482         __ li(a0, Operand(Smi::FromInt(DONT_ENUM)));
2483         __ push(a0);
2484         __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4);
2485         break;
2486
2487       default:
2488         UNREACHABLE();
2489     }
2490   }
2491
2492   // Set both the prototype and constructor to have fast properties, and also
2493   // freeze them in strong mode.
2494   __ CallRuntime(Runtime::kFinalizeClassDefinition, 2);
2495 }
2496
2497
2498 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2499   __ mov(a0, result_register());
2500   __ pop(a1);
2501   Handle<Code> code =
2502       CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
2503   JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
2504   CallIC(code, expr->BinaryOperationFeedbackId());
2505   patch_site.EmitPatchInfo();
2506   context()->Plug(v0);
2507 }
2508
2509
2510 void FullCodeGenerator::EmitAssignment(Expression* expr,
2511                                        FeedbackVectorICSlot slot) {
2512   DCHECK(expr->IsValidReferenceExpressionOrThis());
2513
2514   Property* prop = expr->AsProperty();
2515   LhsKind assign_type = Property::GetAssignType(prop);
2516
2517   switch (assign_type) {
2518     case VARIABLE: {
2519       Variable* var = expr->AsVariableProxy()->var();
2520       EffectContext context(this);
2521       EmitVariableAssignment(var, Token::ASSIGN, slot);
2522       break;
2523     }
2524     case NAMED_PROPERTY: {
2525       __ push(result_register());  // Preserve value.
2526       VisitForAccumulatorValue(prop->obj());
2527       __ mov(StoreDescriptor::ReceiverRegister(), result_register());
2528       __ pop(StoreDescriptor::ValueRegister());  // Restore value.
2529       __ li(StoreDescriptor::NameRegister(),
2530             Operand(prop->key()->AsLiteral()->value()));
2531       if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2532       CallStoreIC();
2533       break;
2534     }
2535     case NAMED_SUPER_PROPERTY: {
2536       __ Push(v0);
2537       VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2538       VisitForAccumulatorValue(
2539           prop->obj()->AsSuperPropertyReference()->home_object());
2540       // stack: value, this; v0: home_object
2541       Register scratch = a2;
2542       Register scratch2 = a3;
2543       __ mov(scratch, result_register());             // home_object
2544       __ lw(v0, MemOperand(sp, kPointerSize));        // value
2545       __ lw(scratch2, MemOperand(sp, 0));             // this
2546       __ sw(scratch2, MemOperand(sp, kPointerSize));  // this
2547       __ sw(scratch, MemOperand(sp, 0));              // home_object
2548       // stack: this, home_object; v0: value
2549       EmitNamedSuperPropertyStore(prop);
2550       break;
2551     }
2552     case KEYED_SUPER_PROPERTY: {
2553       __ Push(v0);
2554       VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2555       VisitForStackValue(
2556           prop->obj()->AsSuperPropertyReference()->home_object());
2557       VisitForAccumulatorValue(prop->key());
2558       Register scratch = a2;
2559       Register scratch2 = a3;
2560       __ lw(scratch2, MemOperand(sp, 2 * kPointerSize));  // value
2561       // stack: value, this, home_object; v0: key, a3: value
2562       __ lw(scratch, MemOperand(sp, kPointerSize));  // this
2563       __ sw(scratch, MemOperand(sp, 2 * kPointerSize));
2564       __ lw(scratch, MemOperand(sp, 0));  // home_object
2565       __ sw(scratch, MemOperand(sp, kPointerSize));
2566       __ sw(v0, MemOperand(sp, 0));
2567       __ Move(v0, scratch2);
2568       // stack: this, home_object, key; v0: value.
2569       EmitKeyedSuperPropertyStore(prop);
2570       break;
2571     }
2572     case KEYED_PROPERTY: {
2573       __ push(result_register());  // Preserve value.
2574       VisitForStackValue(prop->obj());
2575       VisitForAccumulatorValue(prop->key());
2576       __ mov(StoreDescriptor::NameRegister(), result_register());
2577       __ Pop(StoreDescriptor::ValueRegister(),
2578              StoreDescriptor::ReceiverRegister());
2579       if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2580       Handle<Code> ic =
2581           CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2582       CallIC(ic);
2583       break;
2584     }
2585   }
2586   context()->Plug(v0);
2587 }
2588
2589
2590 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2591     Variable* var, MemOperand location) {
2592   __ sw(result_register(), location);
2593   if (var->IsContextSlot()) {
2594     // RecordWrite may destroy all its register arguments.
2595     __ Move(a3, result_register());
2596     int offset = Context::SlotOffset(var->index());
2597     __ RecordWriteContextSlot(
2598         a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2599   }
2600 }
2601
2602
2603 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
2604                                                FeedbackVectorICSlot slot) {
2605   if (var->IsUnallocated()) {
2606     // Global var, const, or let.
2607     __ mov(StoreDescriptor::ValueRegister(), result_register());
2608     __ li(StoreDescriptor::NameRegister(), Operand(var->name()));
2609     __ lw(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2610     if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2611     CallStoreIC();
2612
2613   } else if (var->IsGlobalSlot()) {
2614     // Global var, const, or let.
2615     DCHECK(var->index() > 0);
2616     DCHECK(var->IsStaticGlobalObjectProperty());
2617     DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0));
2618     __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register());
2619     int const slot = var->index();
2620     int const depth = scope()->ContextChainLength(var->scope());
2621     if (depth <= StoreGlobalViaContextStub::kMaximumDepth) {
2622       __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot));
2623       StoreGlobalViaContextStub stub(isolate(), depth, language_mode());
2624       __ CallStub(&stub);
2625     } else {
2626       __ Push(Smi::FromInt(slot));
2627       __ Push(a0);
2628       __ CallRuntime(is_strict(language_mode())
2629                          ? Runtime::kStoreGlobalViaContext_Strict
2630                          : Runtime::kStoreGlobalViaContext_Sloppy,
2631                      2);
2632     }
2633
2634   } else if (var->mode() == LET && op != Token::INIT_LET) {
2635     // Non-initializing assignment to let variable needs a write barrier.
2636     DCHECK(!var->IsLookupSlot());
2637     DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2638     Label assign;
2639     MemOperand location = VarOperand(var, a1);
2640     __ lw(a3, location);
2641     __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2642     __ Branch(&assign, ne, a3, Operand(t0));
2643     __ li(a3, Operand(var->name()));
2644     __ push(a3);
2645     __ CallRuntime(Runtime::kThrowReferenceError, 1);
2646     // Perform the assignment.
2647     __ bind(&assign);
2648     EmitStoreToStackLocalOrContextSlot(var, location);
2649
2650   } else if (var->mode() == CONST && op != Token::INIT_CONST) {
2651     // Assignment to const variable needs a write barrier.
2652     DCHECK(!var->IsLookupSlot());
2653     DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2654     Label const_error;
2655     MemOperand location = VarOperand(var, a1);
2656     __ lw(a3, location);
2657     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2658     __ Branch(&const_error, ne, a3, Operand(at));
2659     __ li(a3, Operand(var->name()));
2660     __ push(a3);
2661     __ CallRuntime(Runtime::kThrowReferenceError, 1);
2662     __ bind(&const_error);
2663     __ CallRuntime(Runtime::kThrowConstAssignError, 0);
2664
2665   } else if (var->is_this() && op == Token::INIT_CONST) {
2666     // Initializing assignment to const {this} needs a write barrier.
2667     DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2668     Label uninitialized_this;
2669     MemOperand location = VarOperand(var, a1);
2670     __ lw(a3, location);
2671     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2672     __ Branch(&uninitialized_this, eq, a3, Operand(at));
2673     __ li(a0, Operand(var->name()));
2674     __ Push(a0);
2675     __ CallRuntime(Runtime::kThrowReferenceError, 1);
2676     __ bind(&uninitialized_this);
2677     EmitStoreToStackLocalOrContextSlot(var, location);
2678
2679   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2680     if (var->IsLookupSlot()) {
2681       // Assignment to var.
2682       __ li(a1, Operand(var->name()));
2683       __ li(a0, Operand(Smi::FromInt(language_mode())));
2684       __ Push(v0, cp, a1, a0);  // Value, context, name, language mode.
2685       __ CallRuntime(Runtime::kStoreLookupSlot, 4);
2686     } else {
2687       // Assignment to var or initializing assignment to let/const in harmony
2688       // mode.
2689       DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2690       MemOperand location = VarOperand(var, a1);
2691       if (generate_debug_code_ && op == Token::INIT_LET) {
2692         // Check for an uninitialized let binding.
2693         __ lw(a2, location);
2694         __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2695         __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2696       }
2697       EmitStoreToStackLocalOrContextSlot(var, location);
2698     }
2699
2700   } else if (op == Token::INIT_CONST_LEGACY) {
2701     // Const initializers need a write barrier.
2702     DCHECK(!var->IsParameter());  // No const parameters.
2703     if (var->IsLookupSlot()) {
2704       __ li(a0, Operand(var->name()));
2705       __ Push(v0, cp, a0);  // Context and name.
2706       __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
2707     } else {
2708       DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2709       Label skip;
2710       MemOperand location = VarOperand(var, a1);
2711       __ lw(a2, location);
2712       __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2713       __ Branch(&skip, ne, a2, Operand(at));
2714       EmitStoreToStackLocalOrContextSlot(var, location);
2715       __ bind(&skip);
2716     }
2717
2718   } else {
2719     DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY);
2720     if (is_strict(language_mode())) {
2721       __ CallRuntime(Runtime::kThrowConstAssignError, 0);
2722     }
2723     // Silently ignore store in sloppy mode.
2724   }
2725 }
2726
2727
2728 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2729   // Assignment to a property, using a named store IC.
2730   Property* prop = expr->target()->AsProperty();
2731   DCHECK(prop != NULL);
2732   DCHECK(prop->key()->IsLiteral());
2733
2734   __ mov(StoreDescriptor::ValueRegister(), result_register());
2735   __ li(StoreDescriptor::NameRegister(),
2736         Operand(prop->key()->AsLiteral()->value()));
2737   __ pop(StoreDescriptor::ReceiverRegister());
2738   if (FLAG_vector_stores) {
2739     EmitLoadStoreICSlot(expr->AssignmentSlot());
2740     CallStoreIC();
2741   } else {
2742     CallStoreIC(expr->AssignmentFeedbackId());
2743   }
2744
2745   PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2746   context()->Plug(v0);
2747 }
2748
2749
2750 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2751   // Assignment to named property of super.
2752   // v0 : value
2753   // stack : receiver ('this'), home_object
2754   DCHECK(prop != NULL);
2755   Literal* key = prop->key()->AsLiteral();
2756   DCHECK(key != NULL);
2757
2758   __ Push(key->value());
2759   __ Push(v0);
2760   __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
2761                                              : Runtime::kStoreToSuper_Sloppy),
2762                  4);
2763 }
2764
2765
2766 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2767   // Assignment to named property of super.
2768   // v0 : value
2769   // stack : receiver ('this'), home_object, key
2770   DCHECK(prop != NULL);
2771
2772   __ Push(v0);
2773   __ CallRuntime(
2774       (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
2775                                   : Runtime::kStoreKeyedToSuper_Sloppy),
2776       4);
2777 }
2778
2779
2780 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2781   // Assignment to a property, using a keyed store IC.
2782   // Call keyed store IC.
2783   // The arguments are:
2784   // - a0 is the value,
2785   // - a1 is the key,
2786   // - a2 is the receiver.
2787   __ mov(StoreDescriptor::ValueRegister(), result_register());
2788   __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2789   DCHECK(StoreDescriptor::ValueRegister().is(a0));
2790
2791   Handle<Code> ic =
2792       CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2793   if (FLAG_vector_stores) {
2794     EmitLoadStoreICSlot(expr->AssignmentSlot());
2795     CallIC(ic);
2796   } else {
2797     CallIC(ic, expr->AssignmentFeedbackId());
2798   }
2799
2800   PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2801   context()->Plug(v0);
2802 }
2803
2804
2805 void FullCodeGenerator::VisitProperty(Property* expr) {
2806   Comment cmnt(masm_, "[ Property");
2807   SetExpressionPosition(expr);
2808
2809   Expression* key = expr->key();
2810
2811   if (key->IsPropertyName()) {
2812     if (!expr->IsSuperAccess()) {
2813       VisitForAccumulatorValue(expr->obj());
2814       __ Move(LoadDescriptor::ReceiverRegister(), v0);
2815       EmitNamedPropertyLoad(expr);
2816     } else {
2817       VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2818       VisitForStackValue(
2819           expr->obj()->AsSuperPropertyReference()->home_object());
2820       EmitNamedSuperPropertyLoad(expr);
2821     }
2822   } else {
2823     if (!expr->IsSuperAccess()) {
2824       VisitForStackValue(expr->obj());
2825       VisitForAccumulatorValue(expr->key());
2826       __ Move(LoadDescriptor::NameRegister(), v0);
2827       __ pop(LoadDescriptor::ReceiverRegister());
2828       EmitKeyedPropertyLoad(expr);
2829     } else {
2830       VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var());
2831       VisitForStackValue(
2832           expr->obj()->AsSuperPropertyReference()->home_object());
2833       VisitForStackValue(expr->key());
2834       EmitKeyedSuperPropertyLoad(expr);
2835     }
2836   }
2837   PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2838   context()->Plug(v0);
2839 }
2840
2841
2842 void FullCodeGenerator::CallIC(Handle<Code> code,
2843                                TypeFeedbackId id) {
2844   ic_total_count_++;
2845   __ Call(code, RelocInfo::CODE_TARGET, id);
2846 }
2847
2848
2849 // Code common for calls using the IC.
2850 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2851   Expression* callee = expr->expression();
2852
2853   CallICState::CallType call_type =
2854       callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
2855
2856   // Get the target function.
2857   if (call_type == CallICState::FUNCTION) {
2858     { StackValueContext context(this);
2859       EmitVariableLoad(callee->AsVariableProxy());
2860       PrepareForBailout(callee, NO_REGISTERS);
2861     }
2862     // Push undefined as receiver. This is patched in the method prologue if it
2863     // is a sloppy mode method.
2864     __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2865     __ push(at);
2866   } else {
2867     // Load the function from the receiver.
2868     DCHECK(callee->IsProperty());
2869     DCHECK(!callee->AsProperty()->IsSuperAccess());
2870     __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2871     EmitNamedPropertyLoad(callee->AsProperty());
2872     PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2873     // Push the target function under the receiver.
2874     __ lw(at, MemOperand(sp, 0));
2875     __ push(at);
2876     __ sw(v0, MemOperand(sp, kPointerSize));
2877   }
2878
2879   EmitCall(expr, call_type);
2880 }
2881
2882
2883 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2884   SetExpressionPosition(expr);
2885   Expression* callee = expr->expression();
2886   DCHECK(callee->IsProperty());
2887   Property* prop = callee->AsProperty();
2888   DCHECK(prop->IsSuperAccess());
2889
2890   Literal* key = prop->key()->AsLiteral();
2891   DCHECK(!key->value()->IsSmi());
2892   // Load the function from the receiver.
2893   const Register scratch = a1;
2894   SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2895   VisitForAccumulatorValue(super_ref->home_object());
2896   __ mov(scratch, v0);
2897   VisitForAccumulatorValue(super_ref->this_var());
2898   __ Push(scratch, v0, v0, scratch);
2899   __ Push(key->value());
2900   __ Push(Smi::FromInt(language_mode()));
2901
2902   // Stack here:
2903   //  - home_object
2904   //  - this (receiver)
2905   //  - this (receiver) <-- LoadFromSuper will pop here and below.
2906   //  - home_object
2907   //  - key
2908   //  - language_mode
2909   __ CallRuntime(Runtime::kLoadFromSuper, 4);
2910
2911   // Replace home_object with target function.
2912   __ sw(v0, MemOperand(sp, kPointerSize));
2913
2914   // Stack here:
2915   // - target function
2916   // - this (receiver)
2917   EmitCall(expr, CallICState::METHOD);
2918 }
2919
2920
2921 // Code common for calls using the IC.
2922 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2923                                                 Expression* key) {
2924   // Load the key.
2925   VisitForAccumulatorValue(key);
2926
2927   Expression* callee = expr->expression();
2928
2929   // Load the function from the receiver.
2930   DCHECK(callee->IsProperty());
2931   __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2932   __ Move(LoadDescriptor::NameRegister(), v0);
2933   EmitKeyedPropertyLoad(callee->AsProperty());
2934   PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2935
2936   // Push the target function under the receiver.
2937   __ lw(at, MemOperand(sp, 0));
2938   __ push(at);
2939   __ sw(v0, MemOperand(sp, kPointerSize));
2940
2941   EmitCall(expr, CallICState::METHOD);
2942 }
2943
2944
2945 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2946   Expression* callee = expr->expression();
2947   DCHECK(callee->IsProperty());
2948   Property* prop = callee->AsProperty();
2949   DCHECK(prop->IsSuperAccess());
2950
2951   SetExpressionPosition(prop);
2952   // Load the function from the receiver.
2953   const Register scratch = a1;
2954   SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2955   VisitForAccumulatorValue(super_ref->home_object());
2956   __ Move(scratch, v0);
2957   VisitForAccumulatorValue(super_ref->this_var());
2958   __ Push(scratch, v0, v0, scratch);
2959   VisitForStackValue(prop->key());
2960   __ Push(Smi::FromInt(language_mode()));
2961
2962   // Stack here:
2963   //  - home_object
2964   //  - this (receiver)
2965   //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2966   //  - home_object
2967   //  - key
2968   //  - language_mode
2969   __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
2970
2971   // Replace home_object with target function.
2972   __ sw(v0, MemOperand(sp, kPointerSize));
2973
2974   // Stack here:
2975   // - target function
2976   // - this (receiver)
2977   EmitCall(expr, CallICState::METHOD);
2978 }
2979
2980
2981 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
2982   // Load the arguments.
2983   ZoneList<Expression*>* args = expr->arguments();
2984   int arg_count = args->length();
2985   for (int i = 0; i < arg_count; i++) {
2986     VisitForStackValue(args->at(i));
2987   }
2988
2989   // Record source position of the IC call.
2990   SetCallPosition(expr, arg_count);
2991   Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
2992   __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
2993   __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2994   // Don't assign a type feedback id to the IC, since type feedback is provided
2995   // by the vector above.
2996   CallIC(ic);
2997
2998   RecordJSReturnSite(expr);
2999   // Restore context register.
3000   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3001   context()->DropAndPlug(1, v0);
3002 }
3003
3004
3005 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
3006   // t3: copy of the first argument or undefined if it doesn't exist.
3007   if (arg_count > 0) {
3008     __ lw(t3, MemOperand(sp, arg_count * kPointerSize));
3009   } else {
3010     __ LoadRoot(t3, Heap::kUndefinedValueRootIndex);
3011   }
3012
3013   // t2: the receiver of the enclosing function.
3014   __ lw(t2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3015
3016   // t1: the language mode.
3017   __ li(t1, Operand(Smi::FromInt(language_mode())));
3018
3019   // t0: the start position of the scope the calls resides in.
3020   __ li(t0, Operand(Smi::FromInt(scope()->start_position())));
3021
3022   // Do the runtime call.
3023   __ Push(t3, t2, t1, t0);
3024   __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
3025 }
3026
3027
3028 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
3029 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
3030   VariableProxy* callee = expr->expression()->AsVariableProxy();
3031   if (callee->var()->IsLookupSlot()) {
3032     Label slow, done;
3033
3034     SetExpressionPosition(callee);
3035     // Generate code for loading from variables potentially shadowed by
3036     // eval-introduced variables.
3037     EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
3038
3039     __ bind(&slow);
3040     // Call the runtime to find the function to call (returned in v0)
3041     // and the object holding it (returned in v1).
3042     DCHECK(!context_register().is(a2));
3043     __ li(a2, Operand(callee->name()));
3044     __ Push(context_register(), a2);
3045     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
3046     __ Push(v0, v1);  // Function, receiver.
3047     PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
3048
3049     // If fast case code has been generated, emit code to push the
3050     // function and receiver and have the slow path jump around this
3051     // code.
3052     if (done.is_linked()) {
3053       Label call;
3054       __ Branch(&call);
3055       __ bind(&done);
3056       // Push function.
3057       __ push(v0);
3058       // The receiver is implicitly the global receiver. Indicate this
3059       // by passing the hole to the call function stub.
3060       __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
3061       __ push(a1);
3062       __ bind(&call);
3063     }
3064   } else {
3065     VisitForStackValue(callee);
3066     // refEnv.WithBaseObject()
3067     __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
3068     __ push(a2);  // Reserved receiver slot.
3069   }
3070 }
3071
3072
3073 void FullCodeGenerator::VisitCall(Call* expr) {
3074 #ifdef DEBUG
3075   // We want to verify that RecordJSReturnSite gets called on all paths
3076   // through this function.  Avoid early returns.
3077   expr->return_is_recorded_ = false;
3078 #endif
3079
3080   Comment cmnt(masm_, "[ Call");
3081   Expression* callee = expr->expression();
3082   Call::CallType call_type = expr->GetCallType(isolate());
3083
3084   if (call_type == Call::POSSIBLY_EVAL_CALL) {
3085     // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
3086     // to resolve the function we need to call.  Then we call the resolved
3087     // function using the given arguments.
3088     ZoneList<Expression*>* args = expr->arguments();
3089     int arg_count = args->length();
3090     PushCalleeAndWithBaseObject(expr);
3091
3092     // Push the arguments.
3093     for (int i = 0; i < arg_count; i++) {
3094       VisitForStackValue(args->at(i));
3095     }
3096
3097     // Push a copy of the function (found below the arguments) and
3098     // resolve eval.
3099     __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3100     __ push(a1);
3101     EmitResolvePossiblyDirectEval(arg_count);
3102
3103     // Touch up the stack with the resolved function.
3104     __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
3105
3106     PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
3107     // Record source position for debugger.
3108     SetCallPosition(expr, arg_count);
3109     CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
3110     __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3111     __ CallStub(&stub);
3112     RecordJSReturnSite(expr);
3113     // Restore context register.
3114     __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3115     context()->DropAndPlug(1, v0);
3116   } else if (call_type == Call::GLOBAL_CALL) {
3117     EmitCallWithLoadIC(expr);
3118   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
3119     // Call to a lookup slot (dynamically introduced variable).
3120     PushCalleeAndWithBaseObject(expr);
3121     EmitCall(expr);
3122   } else if (call_type == Call::PROPERTY_CALL) {
3123     Property* property = callee->AsProperty();
3124     bool is_named_call = property->key()->IsPropertyName();
3125     if (property->IsSuperAccess()) {
3126       if (is_named_call) {
3127         EmitSuperCallWithLoadIC(expr);
3128       } else {
3129         EmitKeyedSuperCallWithLoadIC(expr);
3130       }
3131     } else {
3132         VisitForStackValue(property->obj());
3133       if (is_named_call) {
3134         EmitCallWithLoadIC(expr);
3135       } else {
3136         EmitKeyedCallWithLoadIC(expr, property->key());
3137       }
3138     }
3139   } else if (call_type == Call::SUPER_CALL) {
3140     EmitSuperConstructorCall(expr);
3141   } else {
3142     DCHECK(call_type == Call::OTHER_CALL);
3143     // Call to an arbitrary expression not handled specially above.
3144       VisitForStackValue(callee);
3145     __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
3146     __ push(a1);
3147     // Emit function call.
3148     EmitCall(expr);
3149   }
3150
3151 #ifdef DEBUG
3152   // RecordJSReturnSite should have been called.
3153   DCHECK(expr->return_is_recorded_);
3154 #endif
3155 }
3156
3157
3158 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
3159   Comment cmnt(masm_, "[ CallNew");
3160   // According to ECMA-262, section 11.2.2, page 44, the function
3161   // expression in new calls must be evaluated before the
3162   // arguments.
3163
3164   // Push constructor on the stack.  If it's not a function it's used as
3165   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
3166   // ignored.g
3167   DCHECK(!expr->expression()->IsSuperPropertyReference());
3168   VisitForStackValue(expr->expression());
3169
3170   // Push the arguments ("left-to-right") on the stack.
3171   ZoneList<Expression*>* args = expr->arguments();
3172   int arg_count = args->length();
3173   for (int i = 0; i < arg_count; i++) {
3174     VisitForStackValue(args->at(i));
3175   }
3176
3177   // Call the construct call builtin that handles allocation and
3178   // constructor invocation.
3179   SetConstructCallPosition(expr);
3180
3181   // Load function and argument count into a1 and a0.
3182   __ li(a0, Operand(arg_count));
3183   __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
3184
3185   // Record call targets in unoptimized code.
3186   __ li(a2, FeedbackVector());
3187   __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
3188
3189   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
3190   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
3191   PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
3192   // Restore context register.
3193   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3194   context()->Plug(v0);
3195 }
3196
3197
3198 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
3199   SuperCallReference* super_call_ref =
3200       expr->expression()->AsSuperCallReference();
3201   DCHECK_NOT_NULL(super_call_ref);
3202
3203   EmitLoadSuperConstructor(super_call_ref);
3204   __ push(result_register());
3205
3206   // Push the arguments ("left-to-right") on the stack.
3207   ZoneList<Expression*>* args = expr->arguments();
3208   int arg_count = args->length();
3209   for (int i = 0; i < arg_count; i++) {
3210     VisitForStackValue(args->at(i));
3211   }
3212
3213   // Call the construct call builtin that handles allocation and
3214   // constructor invocation.
3215   SetConstructCallPosition(expr);
3216
3217   // Load original constructor into t0.
3218   VisitForAccumulatorValue(super_call_ref->new_target_var());
3219   __ mov(t0, result_register());
3220
3221   // Load function and argument count into a1 and a0.
3222   __ li(a0, Operand(arg_count));
3223   __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
3224
3225   // Record call targets in unoptimized code.
3226   __ li(a2, FeedbackVector());
3227   __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
3228
3229   CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
3230   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
3231
3232   RecordJSReturnSite(expr);
3233
3234   // Restore context register.
3235   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3236   context()->Plug(v0);
3237 }
3238
3239
3240 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
3241   ZoneList<Expression*>* args = expr->arguments();
3242   DCHECK(args->length() == 1);
3243
3244   VisitForAccumulatorValue(args->at(0));
3245
3246   Label materialize_true, materialize_false;
3247   Label* if_true = NULL;
3248   Label* if_false = NULL;
3249   Label* fall_through = NULL;
3250   context()->PrepareTest(&materialize_true, &materialize_false,
3251                          &if_true, &if_false, &fall_through);
3252
3253   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3254   __ SmiTst(v0, t0);
3255   Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through);
3256
3257   context()->Plug(if_true, if_false);
3258 }
3259
3260
3261 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
3262   ZoneList<Expression*>* args = expr->arguments();
3263   DCHECK(args->length() == 1);
3264
3265   VisitForAccumulatorValue(args->at(0));
3266
3267   Label materialize_true, materialize_false;
3268   Label* if_true = NULL;
3269   Label* if_false = NULL;
3270   Label* fall_through = NULL;
3271   context()->PrepareTest(&materialize_true, &materialize_false,
3272                          &if_true, &if_false, &fall_through);
3273
3274   __ JumpIfSmi(v0, if_false);
3275   __ GetObjectType(v0, a1, a1);
3276   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3277   Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE),
3278         if_true, if_false, fall_through);
3279
3280   context()->Plug(if_true, if_false);
3281 }
3282
3283
3284 void FullCodeGenerator::EmitIsSimdValue(CallRuntime* expr) {
3285   ZoneList<Expression*>* args = expr->arguments();
3286   DCHECK(args->length() == 1);
3287
3288   VisitForAccumulatorValue(args->at(0));
3289
3290   Label materialize_true, materialize_false;
3291   Label* if_true = NULL;
3292   Label* if_false = NULL;
3293   Label* fall_through = NULL;
3294   context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
3295                          &if_false, &fall_through);
3296
3297   __ JumpIfSmi(v0, if_false);
3298   __ GetObjectType(v0, a1, a1);
3299   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3300   Split(eq, a1, Operand(SIMD128_VALUE_TYPE), if_true, if_false, fall_through);
3301
3302   context()->Plug(if_true, if_false);
3303 }
3304
3305
3306 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
3307   ZoneList<Expression*>* args = expr->arguments();
3308   DCHECK(args->length() == 1);
3309
3310   VisitForAccumulatorValue(args->at(0));
3311
3312   Label materialize_true, materialize_false;
3313   Label* if_true = NULL;
3314   Label* if_false = NULL;
3315   Label* fall_through = NULL;
3316   context()->PrepareTest(&materialize_true, &materialize_false,
3317                          &if_true, &if_false, &fall_through);
3318
3319   __ JumpIfSmi(v0, if_false);
3320   __ GetObjectType(v0, a1, a2);
3321   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3322   __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE));
3323   __ Branch(if_false);
3324
3325   context()->Plug(if_true, if_false);
3326 }
3327
3328
3329 void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
3330   ZoneList<Expression*>* args = expr->arguments();
3331   DCHECK(args->length() == 1);
3332
3333   VisitForAccumulatorValue(args->at(0));
3334
3335   Label materialize_true, materialize_false;
3336   Label* if_true = NULL;
3337   Label* if_false = NULL;
3338   Label* fall_through = NULL;
3339   context()->PrepareTest(&materialize_true, &materialize_false,
3340                          &if_true, &if_false, &fall_through);
3341
3342   __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
3343   __ lw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
3344   __ lw(a1, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
3345   __ li(t0, 0x80000000);
3346   Label not_nan;
3347   __ Branch(&not_nan, ne, a2, Operand(t0));
3348   __ mov(t0, zero_reg);
3349   __ mov(a2, a1);
3350   __ bind(&not_nan);
3351
3352   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3353   Split(eq, a2, Operand(t0), if_true, if_false, fall_through);
3354
3355   context()->Plug(if_true, if_false);
3356 }
3357
3358
3359 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
3360   ZoneList<Expression*>* args = expr->arguments();
3361   DCHECK(args->length() == 1);
3362
3363   VisitForAccumulatorValue(args->at(0));
3364
3365   Label materialize_true, materialize_false;
3366   Label* if_true = NULL;
3367   Label* if_false = NULL;
3368   Label* fall_through = NULL;
3369   context()->PrepareTest(&materialize_true, &materialize_false,
3370                          &if_true, &if_false, &fall_through);
3371
3372   __ JumpIfSmi(v0, if_false);
3373   __ GetObjectType(v0, a1, a1);
3374   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3375   Split(eq, a1, Operand(JS_ARRAY_TYPE),
3376         if_true, if_false, fall_through);
3377
3378   context()->Plug(if_true, if_false);
3379 }
3380
3381
3382 void FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
3383   ZoneList<Expression*>* args = expr->arguments();
3384   DCHECK(args->length() == 1);
3385
3386   VisitForAccumulatorValue(args->at(0));
3387
3388   Label materialize_true, materialize_false;
3389   Label* if_true = NULL;
3390   Label* if_false = NULL;
3391   Label* fall_through = NULL;
3392   context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
3393                          &if_false, &fall_through);
3394
3395   __ JumpIfSmi(v0, if_false);
3396   __ GetObjectType(v0, a1, a1);
3397   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3398   Split(eq, a1, Operand(JS_TYPED_ARRAY_TYPE), if_true, if_false, fall_through);
3399
3400   context()->Plug(if_true, if_false);
3401 }
3402
3403
3404 void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
3405   ZoneList<Expression*>* args = expr->arguments();
3406   DCHECK(args->length() == 1);
3407
3408   VisitForAccumulatorValue(args->at(0));
3409
3410   Label materialize_true, materialize_false;
3411   Label* if_true = NULL;
3412   Label* if_false = NULL;
3413   Label* fall_through = NULL;
3414   context()->PrepareTest(&materialize_true, &materialize_false,
3415                          &if_true, &if_false, &fall_through);
3416
3417   __ JumpIfSmi(v0, if_false);
3418   __ GetObjectType(v0, a1, a1);
3419   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3420   Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through);
3421
3422   context()->Plug(if_true, if_false);
3423 }
3424
3425
3426 void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
3427   ZoneList<Expression*>* args = expr->arguments();
3428   DCHECK(args->length() == 1);
3429
3430   VisitForAccumulatorValue(args->at(0));
3431
3432   Label materialize_true, materialize_false;
3433   Label* if_true = NULL;
3434   Label* if_false = NULL;
3435   Label* fall_through = NULL;
3436   context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
3437                          &if_false, &fall_through);
3438
3439   __ JumpIfSmi(v0, if_false);
3440   Register map = a1;
3441   Register type_reg = a2;
3442   __ GetObjectType(v0, map, type_reg);
3443   __ Subu(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
3444   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3445   Split(ls, type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE),
3446         if_true, if_false, fall_through);
3447
3448   context()->Plug(if_true, if_false);
3449 }
3450
3451
3452 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
3453   DCHECK(expr->arguments()->length() == 0);
3454
3455   Label materialize_true, materialize_false;
3456   Label* if_true = NULL;
3457   Label* if_false = NULL;
3458   Label* fall_through = NULL;
3459   context()->PrepareTest(&materialize_true, &materialize_false,
3460                          &if_true, &if_false, &fall_through);
3461
3462   // Get the frame pointer for the calling frame.
3463   __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3464
3465   // Skip the arguments adaptor frame if it exists.
3466   Label check_frame_marker;
3467   __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset));
3468   __ Branch(&check_frame_marker, ne,
3469             a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3470   __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
3471
3472   // Check the marker in the calling frame.
3473   __ bind(&check_frame_marker);
3474   __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset));
3475   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3476   Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)),
3477         if_true, if_false, fall_through);
3478
3479   context()->Plug(if_true, if_false);
3480 }
3481
3482
3483 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
3484   ZoneList<Expression*>* args = expr->arguments();
3485   DCHECK(args->length() == 2);
3486
3487   // Load the two objects into registers and perform the comparison.
3488   VisitForStackValue(args->at(0));
3489   VisitForAccumulatorValue(args->at(1));
3490
3491   Label materialize_true, materialize_false;
3492   Label* if_true = NULL;
3493   Label* if_false = NULL;
3494   Label* fall_through = NULL;
3495   context()->PrepareTest(&materialize_true, &materialize_false,
3496                          &if_true, &if_false, &fall_through);
3497
3498   __ pop(a1);
3499   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3500   Split(eq, v0, Operand(a1), if_true, if_false, fall_through);
3501
3502   context()->Plug(if_true, if_false);
3503 }
3504
3505
3506 void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
3507   ZoneList<Expression*>* args = expr->arguments();
3508   DCHECK(args->length() == 1);
3509
3510   // ArgumentsAccessStub expects the key in a1 and the formal
3511   // parameter count in a0.
3512   VisitForAccumulatorValue(args->at(0));
3513   __ mov(a1, v0);
3514   __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
3515   ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
3516   __ CallStub(&stub);
3517   context()->Plug(v0);
3518 }
3519
3520
3521 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
3522   DCHECK(expr->arguments()->length() == 0);
3523   Label exit;
3524   // Get the number of formal parameters.
3525   __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
3526
3527   // Check if the calling frame is an arguments adaptor frame.
3528   __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3529   __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset));
3530   __ Branch(&exit, ne, a3,
3531             Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3532
3533   // Arguments adaptor case: Read the arguments length from the
3534   // adaptor frame.
3535   __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3536
3537   __ bind(&exit);
3538   context()->Plug(v0);
3539 }
3540
3541
3542 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
3543   ZoneList<Expression*>* args = expr->arguments();
3544   DCHECK(args->length() == 1);
3545   Label done, null, function, non_function_constructor;
3546
3547   VisitForAccumulatorValue(args->at(0));
3548
3549   // If the object is a smi, we return null.
3550   __ JumpIfSmi(v0, &null);
3551
3552   // Check that the object is a JS object but take special care of JS
3553   // functions to make sure they have 'Function' as their class.
3554   // Assume that there are only two callable types, and one of them is at
3555   // either end of the type range for JS object types. Saves extra comparisons.
3556   STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
3557   __ GetObjectType(v0, v0, a1);  // Map is now in v0.
3558   __ Branch(&null, lt, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
3559
3560   STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
3561                 FIRST_SPEC_OBJECT_TYPE + 1);
3562   __ Branch(&function, eq, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
3563
3564   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
3565                 LAST_SPEC_OBJECT_TYPE - 1);
3566   __ Branch(&function, eq, a1, Operand(LAST_SPEC_OBJECT_TYPE));
3567   // Assume that there is no larger type.
3568   STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
3569
3570   // Check if the constructor in the map is a JS function.
3571   Register instance_type = a2;
3572   __ GetMapConstructor(v0, v0, a1, instance_type);
3573   __ Branch(&non_function_constructor, ne, instance_type,
3574             Operand(JS_FUNCTION_TYPE));
3575
3576   // v0 now contains the constructor function. Grab the
3577   // instance class name from there.
3578   __ lw(v0, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset));
3579   __ lw(v0, FieldMemOperand(v0, SharedFunctionInfo::kInstanceClassNameOffset));
3580   __ Branch(&done);
3581
3582   // Functions have class 'Function'.
3583   __ bind(&function);
3584   __ LoadRoot(v0, Heap::kFunction_stringRootIndex);
3585   __ jmp(&done);
3586
3587   // Objects with a non-function constructor have class 'Object'.
3588   __ bind(&non_function_constructor);
3589   __ LoadRoot(v0, Heap::kObject_stringRootIndex);
3590   __ jmp(&done);
3591
3592   // Non-JS objects have class null.
3593   __ bind(&null);
3594   __ LoadRoot(v0, Heap::kNullValueRootIndex);
3595
3596   // All done.
3597   __ bind(&done);
3598
3599   context()->Plug(v0);
3600 }
3601
3602
3603 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
3604   ZoneList<Expression*>* args = expr->arguments();
3605   DCHECK(args->length() == 1);
3606
3607   VisitForAccumulatorValue(args->at(0));  // Load the object.
3608
3609   Label done;
3610   // If the object is a smi return the object.
3611   __ JumpIfSmi(v0, &done);
3612   // If the object is not a value type, return the object.
3613   __ GetObjectType(v0, a1, a1);
3614   __ Branch(&done, ne, a1, Operand(JS_VALUE_TYPE));
3615
3616   __ lw(v0, FieldMemOperand(v0, JSValue::kValueOffset));
3617
3618   __ bind(&done);
3619   context()->Plug(v0);
3620 }
3621
3622
3623 void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
3624   ZoneList<Expression*>* args = expr->arguments();
3625   DCHECK_EQ(1, args->length());
3626
3627   VisitForAccumulatorValue(args->at(0));
3628
3629   Label materialize_true, materialize_false;
3630   Label* if_true = nullptr;
3631   Label* if_false = nullptr;
3632   Label* fall_through = nullptr;
3633   context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
3634                          &if_false, &fall_through);
3635
3636   __ JumpIfSmi(v0, if_false);
3637   __ GetObjectType(v0, a1, a1);
3638   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3639   Split(eq, a1, Operand(JS_DATE_TYPE), if_true, if_false, fall_through);
3640
3641   context()->Plug(if_true, if_false);
3642 }
3643
3644
3645 void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
3646   ZoneList<Expression*>* args = expr->arguments();
3647   DCHECK(args->length() == 2);
3648   DCHECK_NOT_NULL(args->at(1)->AsLiteral());
3649   Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
3650
3651   VisitForAccumulatorValue(args->at(0));  // Load the object.
3652
3653   Register object = v0;
3654   Register result = v0;
3655   Register scratch0 = t5;
3656   Register scratch1 = a1;
3657
3658   if (index->value() == 0) {
3659     __ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
3660   } else {
3661     Label runtime, done;
3662     if (index->value() < JSDate::kFirstUncachedField) {
3663       ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
3664       __ li(scratch1, Operand(stamp));
3665       __ lw(scratch1, MemOperand(scratch1));
3666       __ lw(scratch0, FieldMemOperand(object, JSDate::kCacheStampOffset));
3667       __ Branch(&runtime, ne, scratch1, Operand(scratch0));
3668       __ lw(result, FieldMemOperand(object, JSDate::kValueOffset +
3669                                             kPointerSize * index->value()));
3670       __ jmp(&done);
3671     }
3672     __ bind(&runtime);
3673     __ PrepareCallCFunction(2, scratch1);
3674     __ li(a1, Operand(index));
3675     __ Move(a0, object);
3676     __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
3677     __ bind(&done);
3678   }
3679
3680   context()->Plug(result);
3681 }
3682
3683
3684 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3685   ZoneList<Expression*>* args = expr->arguments();
3686   DCHECK_EQ(3, args->length());
3687
3688   Register string = v0;
3689   Register index = a1;
3690   Register value = a2;
3691
3692   VisitForStackValue(args->at(0));        // index
3693   VisitForStackValue(args->at(1));        // value
3694   VisitForAccumulatorValue(args->at(2));  // string
3695   __ Pop(index, value);
3696
3697   if (FLAG_debug_code) {
3698     __ SmiTst(value, at);
3699     __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3700     __ SmiTst(index, at);
3701     __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3702     __ SmiUntag(index, index);
3703     static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3704     Register scratch = t5;
3705     __ EmitSeqStringSetCharCheck(
3706         string, index, value, scratch, one_byte_seq_type);
3707     __ SmiTag(index, index);
3708   }
3709
3710   __ SmiUntag(value, value);
3711   __ Addu(at,
3712           string,
3713           Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3714   __ SmiUntag(index);
3715   __ Addu(at, at, index);
3716   __ sb(value, MemOperand(at));
3717   context()->Plug(string);
3718 }
3719
3720
3721 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3722   ZoneList<Expression*>* args = expr->arguments();
3723   DCHECK_EQ(3, args->length());
3724
3725   Register string = v0;
3726   Register index = a1;
3727   Register value = a2;
3728
3729   VisitForStackValue(args->at(0));        // index
3730   VisitForStackValue(args->at(1));        // value
3731   VisitForAccumulatorValue(args->at(2));  // string
3732   __ Pop(index, value);
3733
3734   if (FLAG_debug_code) {
3735     __ SmiTst(value, at);
3736     __ Check(eq, kNonSmiValue, at, Operand(zero_reg));
3737     __ SmiTst(index, at);
3738     __ Check(eq, kNonSmiIndex, at, Operand(zero_reg));
3739     __ SmiUntag(index, index);
3740     static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3741     Register scratch = t5;
3742     __ EmitSeqStringSetCharCheck(
3743         string, index, value, scratch, two_byte_seq_type);
3744     __ SmiTag(index, index);
3745   }
3746
3747   __ SmiUntag(value, value);
3748   __ Addu(at,
3749           string,
3750           Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
3751   __ Addu(at, at, index);
3752   STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
3753   __ sh(value, MemOperand(at));
3754     context()->Plug(string);
3755 }
3756
3757
3758 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
3759   ZoneList<Expression*>* args = expr->arguments();
3760   DCHECK(args->length() == 2);
3761
3762   VisitForStackValue(args->at(0));  // Load the object.
3763   VisitForAccumulatorValue(args->at(1));  // Load the value.
3764   __ pop(a1);  // v0 = value. a1 = object.
3765
3766   Label done;
3767   // If the object is a smi, return the value.
3768   __ JumpIfSmi(a1, &done);
3769
3770   // If the object is not a value type, return the value.
3771   __ GetObjectType(a1, a2, a2);
3772   __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE));
3773
3774   // Store the value.
3775   __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset));
3776   // Update the write barrier.  Save the value as it will be
3777   // overwritten by the write barrier code and is needed afterward.
3778   __ mov(a2, v0);
3779   __ RecordWriteField(
3780       a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs);
3781
3782   __ bind(&done);
3783   context()->Plug(v0);
3784 }
3785
3786
3787 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
3788   ZoneList<Expression*>* args = expr->arguments();
3789   DCHECK_EQ(args->length(), 1);
3790
3791   // Load the argument into a0 and call the stub.
3792   VisitForAccumulatorValue(args->at(0));
3793   __ mov(a0, result_register());
3794
3795   NumberToStringStub stub(isolate());
3796   __ CallStub(&stub);
3797   context()->Plug(v0);
3798 }
3799
3800
3801 void FullCodeGenerator::EmitToString(CallRuntime* expr) {
3802   ZoneList<Expression*>* args = expr->arguments();
3803   DCHECK_EQ(1, args->length());
3804
3805   // Load the argument into a0 and convert it.
3806   VisitForAccumulatorValue(args->at(0));
3807   __ mov(a0, result_register());
3808
3809   ToStringStub stub(isolate());
3810   __ CallStub(&stub);
3811   context()->Plug(v0);
3812 }
3813
3814
3815 void FullCodeGenerator::EmitToName(CallRuntime* expr) {
3816   ZoneList<Expression*>* args = expr->arguments();
3817   DCHECK_EQ(1, args->length());
3818
3819   // Load the argument into v0 and convert it.
3820   VisitForAccumulatorValue(args->at(0));
3821
3822   Label convert, done_convert;
3823   __ JumpIfSmi(v0, &convert);
3824   STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
3825   __ GetObjectType(v0, a1, a1);
3826   __ Branch(&done_convert, le, a1, Operand(LAST_NAME_TYPE));
3827   __ bind(&convert);
3828   ToStringStub stub(isolate());
3829   __ mov(a0, v0);
3830   __ CallStub(&stub);
3831   __ bind(&done_convert);
3832   context()->Plug(v0);
3833 }
3834
3835
3836 void FullCodeGenerator::EmitToObject(CallRuntime* expr) {
3837   ZoneList<Expression*>* args = expr->arguments();
3838   DCHECK_EQ(1, args->length());
3839
3840   // Load the argument into a0 and convert it.
3841   VisitForAccumulatorValue(args->at(0));
3842   __ mov(a0, result_register());
3843
3844   ToObjectStub stub(isolate());
3845   __ CallStub(&stub);
3846   context()->Plug(v0);
3847 }
3848
3849
3850 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3851   ZoneList<Expression*>* args = expr->arguments();
3852   DCHECK(args->length() == 1);
3853
3854   VisitForAccumulatorValue(args->at(0));
3855
3856   Label done;
3857   StringCharFromCodeGenerator generator(v0, a1);
3858   generator.GenerateFast(masm_);
3859   __ jmp(&done);
3860
3861   NopRuntimeCallHelper call_helper;
3862   generator.GenerateSlow(masm_, call_helper);
3863
3864   __ bind(&done);
3865   context()->Plug(a1);
3866 }
3867
3868
3869 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
3870   ZoneList<Expression*>* args = expr->arguments();
3871   DCHECK(args->length() == 2);
3872
3873   VisitForStackValue(args->at(0));
3874   VisitForAccumulatorValue(args->at(1));
3875   __ mov(a0, result_register());
3876
3877   Register object = a1;
3878   Register index = a0;
3879   Register result = v0;
3880
3881   __ pop(object);
3882
3883   Label need_conversion;
3884   Label index_out_of_range;
3885   Label done;
3886   StringCharCodeAtGenerator generator(object,
3887                                       index,
3888                                       result,
3889                                       &need_conversion,
3890                                       &need_conversion,
3891                                       &index_out_of_range,
3892                                       STRING_INDEX_IS_NUMBER);
3893   generator.GenerateFast(masm_);
3894   __ jmp(&done);
3895
3896   __ bind(&index_out_of_range);
3897   // When the index is out of range, the spec requires us to return
3898   // NaN.
3899   __ LoadRoot(result, Heap::kNanValueRootIndex);
3900   __ jmp(&done);
3901
3902   __ bind(&need_conversion);
3903   // Load the undefined value into the result register, which will
3904   // trigger conversion.
3905   __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
3906   __ jmp(&done);
3907
3908   NopRuntimeCallHelper call_helper;
3909   generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
3910
3911   __ bind(&done);
3912   context()->Plug(result);
3913 }
3914
3915
3916 void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
3917   ZoneList<Expression*>* args = expr->arguments();
3918   DCHECK(args->length() == 2);
3919
3920   VisitForStackValue(args->at(0));
3921   VisitForAccumulatorValue(args->at(1));
3922   __ mov(a0, result_register());
3923
3924   Register object = a1;
3925   Register index = a0;
3926   Register scratch = a3;
3927   Register result = v0;
3928
3929   __ pop(object);
3930
3931   Label need_conversion;
3932   Label index_out_of_range;
3933   Label done;
3934   StringCharAtGenerator generator(object,
3935                                   index,
3936                                   scratch,
3937                                   result,
3938                                   &need_conversion,
3939                                   &need_conversion,
3940                                   &index_out_of_range,
3941                                   STRING_INDEX_IS_NUMBER);
3942   generator.GenerateFast(masm_);
3943   __ jmp(&done);
3944
3945   __ bind(&index_out_of_range);
3946   // When the index is out of range, the spec requires us to return
3947   // the empty string.
3948   __ LoadRoot(result, Heap::kempty_stringRootIndex);
3949   __ jmp(&done);
3950
3951   __ bind(&need_conversion);
3952   // Move smi zero into the result register, which will trigger
3953   // conversion.
3954   __ li(result, Operand(Smi::FromInt(0)));
3955   __ jmp(&done);
3956
3957   NopRuntimeCallHelper call_helper;
3958   generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
3959
3960   __ bind(&done);
3961   context()->Plug(result);
3962 }
3963
3964
3965 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
3966   ZoneList<Expression*>* args = expr->arguments();
3967   DCHECK_EQ(2, args->length());
3968   VisitForStackValue(args->at(0));
3969   VisitForAccumulatorValue(args->at(1));
3970
3971   __ pop(a1);
3972   __ mov(a0, result_register());  // StringAddStub requires args in a0, a1.
3973   StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
3974   __ CallStub(&stub);
3975   context()->Plug(v0);
3976 }
3977
3978
3979 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
3980   ZoneList<Expression*>* args = expr->arguments();
3981   DCHECK_LE(2, args->length());
3982   // Push target, receiver and arguments onto the stack.
3983   for (Expression* const arg : *args) {
3984     VisitForStackValue(arg);
3985   }
3986   // Move target to a1.
3987   int const argc = args->length() - 2;
3988   __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize));
3989   // Call the target.
3990   __ li(a0, Operand(argc));
3991   __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3992   // Restore context register.
3993   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3994   // Discard the function left on TOS.
3995   context()->DropAndPlug(1, v0);
3996 }
3997
3998
3999 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
4000   ZoneList<Expression*>* args = expr->arguments();
4001   DCHECK(args->length() >= 2);
4002
4003   int arg_count = args->length() - 2;  // 2 ~ receiver and function.
4004   for (int i = 0; i < arg_count + 1; i++) {
4005     VisitForStackValue(args->at(i));
4006   }
4007   VisitForAccumulatorValue(args->last());  // Function.
4008
4009   Label runtime, done;
4010   // Check for non-function argument (including proxy).
4011   __ JumpIfSmi(v0, &runtime);
4012   __ GetObjectType(v0, a1, a1);
4013   __ Branch(&runtime, ne, a1, Operand(JS_FUNCTION_TYPE));
4014
4015   // InvokeFunction requires the function in a1. Move it in there.
4016   __ mov(a1, result_register());
4017   ParameterCount count(arg_count);
4018   __ InvokeFunction(a1, count, CALL_FUNCTION, NullCallWrapper());
4019   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4020   __ jmp(&done);
4021
4022   __ bind(&runtime);
4023   __ push(v0);
4024   __ CallRuntime(Runtime::kCallFunction, args->length());
4025   __ bind(&done);
4026
4027   context()->Plug(v0);
4028 }
4029
4030
4031 void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
4032   ZoneList<Expression*>* args = expr->arguments();
4033   DCHECK(args->length() == 2);
4034
4035   // Evaluate new.target and super constructor.
4036   VisitForStackValue(args->at(0));
4037   VisitForStackValue(args->at(1));
4038
4039   // Load original constructor into a3.
4040   __ lw(a3, MemOperand(sp, 1 * kPointerSize));
4041
4042   // Check if the calling frame is an arguments adaptor frame.
4043   Label adaptor_frame, args_set_up, runtime;
4044   __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
4045   __ lw(t0, MemOperand(a2, StandardFrameConstants::kContextOffset));
4046   __ Branch(&adaptor_frame, eq, t0,
4047             Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4048   // default constructor has no arguments, so no adaptor frame means no args.
4049   __ mov(a0, zero_reg);
4050   __ Branch(&args_set_up);
4051
4052   // Copy arguments from adaptor frame.
4053   {
4054     __ bind(&adaptor_frame);
4055     __ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
4056     __ SmiUntag(a1, a1);
4057
4058     __ mov(a0, a1);
4059
4060     // Get arguments pointer in a2.
4061     __ sll(at, a1, kPointerSizeLog2);
4062     __ addu(a2, a2, at);
4063     __ Addu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset));
4064     Label loop;
4065     __ bind(&loop);
4066     // Pre-decrement a2 with kPointerSize on each iteration.
4067     // Pre-decrement in order to skip receiver.
4068     __ Addu(a2, a2, Operand(-kPointerSize));
4069     __ lw(t0, MemOperand(a2));
4070     __ Push(t0);
4071     __ Addu(a1, a1, Operand(-1));
4072     __ Branch(&loop, ne, a1, Operand(zero_reg));
4073   }
4074
4075   __ bind(&args_set_up);
4076   __ sll(at, a0, kPointerSizeLog2);
4077   __ Addu(at, at, Operand(sp));
4078   __ lw(a1, MemOperand(at, 0));
4079   __ Call(isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL);
4080
4081   // Restore context register.
4082   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4083
4084   context()->DropAndPlug(1, result_register());
4085 }
4086
4087
4088 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
4089   RegExpConstructResultStub stub(isolate());
4090   ZoneList<Expression*>* args = expr->arguments();
4091   DCHECK(args->length() == 3);
4092   VisitForStackValue(args->at(0));
4093   VisitForStackValue(args->at(1));
4094   VisitForAccumulatorValue(args->at(2));
4095   __ mov(a0, result_register());
4096   __ pop(a1);
4097   __ pop(a2);
4098   __ CallStub(&stub);
4099   context()->Plug(v0);
4100 }
4101
4102
4103 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
4104   ZoneList<Expression*>* args = expr->arguments();
4105   VisitForAccumulatorValue(args->at(0));
4106
4107   Label materialize_true, materialize_false;
4108   Label* if_true = NULL;
4109   Label* if_false = NULL;
4110   Label* fall_through = NULL;
4111   context()->PrepareTest(&materialize_true, &materialize_false,
4112                          &if_true, &if_false, &fall_through);
4113
4114   __ lw(a0, FieldMemOperand(v0, String::kHashFieldOffset));
4115   __ And(a0, a0, Operand(String::kContainsCachedArrayIndexMask));
4116
4117   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4118   Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through);
4119
4120   context()->Plug(if_true, if_false);
4121 }
4122
4123
4124 void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
4125   ZoneList<Expression*>* args = expr->arguments();
4126   DCHECK(args->length() == 1);
4127   VisitForAccumulatorValue(args->at(0));
4128
4129   __ AssertString(v0);
4130
4131   __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset));
4132   __ IndexFromHash(v0, v0);
4133
4134   context()->Plug(v0);
4135 }
4136
4137
4138 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) {
4139   Label bailout, done, one_char_separator, long_separator,
4140       non_trivial_array, not_size_one_array, loop,
4141       empty_separator_loop, one_char_separator_loop,
4142       one_char_separator_loop_entry, long_separator_loop;
4143   ZoneList<Expression*>* args = expr->arguments();
4144   DCHECK(args->length() == 2);
4145   VisitForStackValue(args->at(1));
4146   VisitForAccumulatorValue(args->at(0));
4147
4148   // All aliases of the same register have disjoint lifetimes.
4149   Register array = v0;
4150   Register elements = no_reg;  // Will be v0.
4151   Register result = no_reg;  // Will be v0.
4152   Register separator = a1;
4153   Register array_length = a2;
4154   Register result_pos = no_reg;  // Will be a2.
4155   Register string_length = a3;
4156   Register string = t0;
4157   Register element = t1;
4158   Register elements_end = t2;
4159   Register scratch1 = t3;
4160   Register scratch2 = t5;
4161   Register scratch3 = t4;
4162
4163   // Separator operand is on the stack.
4164   __ pop(separator);
4165
4166   // Check that the array is a JSArray.
4167   __ JumpIfSmi(array, &bailout);
4168   __ GetObjectType(array, scratch1, scratch2);
4169   __ Branch(&bailout, ne, scratch2, Operand(JS_ARRAY_TYPE));
4170
4171   // Check that the array has fast elements.
4172   __ CheckFastElements(scratch1, scratch2, &bailout);
4173
4174   // If the array has length zero, return the empty string.
4175   __ lw(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
4176   __ SmiUntag(array_length);
4177   __ Branch(&non_trivial_array, ne, array_length, Operand(zero_reg));
4178   __ LoadRoot(v0, Heap::kempty_stringRootIndex);
4179   __ Branch(&done);
4180
4181   __ bind(&non_trivial_array);
4182
4183   // Get the FixedArray containing array's elements.
4184   elements = array;
4185   __ lw(elements, FieldMemOperand(array, JSArray::kElementsOffset));
4186   array = no_reg;  // End of array's live range.
4187
4188   // Check that all array elements are sequential one-byte strings, and
4189   // accumulate the sum of their lengths, as a smi-encoded value.
4190   __ mov(string_length, zero_reg);
4191   __ Addu(element,
4192           elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4193   __ sll(elements_end, array_length, kPointerSizeLog2);
4194   __ Addu(elements_end, element, elements_end);
4195   // Loop condition: while (element < elements_end).
4196   // Live values in registers:
4197   //   elements: Fixed array of strings.
4198   //   array_length: Length of the fixed array of strings (not smi)
4199   //   separator: Separator string
4200   //   string_length: Accumulated sum of string lengths (smi).
4201   //   element: Current array element.
4202   //   elements_end: Array end.
4203   if (generate_debug_code_) {
4204     __ Assert(gt, kNoEmptyArraysHereInEmitFastOneByteArrayJoin, array_length,
4205               Operand(zero_reg));
4206   }
4207   __ bind(&loop);
4208   __ lw(string, MemOperand(element));
4209   __ Addu(element, element, kPointerSize);
4210   __ JumpIfSmi(string, &bailout);
4211   __ lw(scratch1, FieldMemOperand(string, HeapObject::kMapOffset));
4212   __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
4213   __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
4214   __ lw(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
4215   __ AdduAndCheckForOverflow(string_length, string_length, scratch1, scratch3);
4216   __ BranchOnOverflow(&bailout, scratch3);
4217   __ Branch(&loop, lt, element, Operand(elements_end));
4218
4219   // If array_length is 1, return elements[0], a string.
4220   __ Branch(&not_size_one_array, ne, array_length, Operand(1));
4221   __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize));
4222   __ Branch(&done);
4223
4224   __ bind(&not_size_one_array);
4225
4226   // Live values in registers:
4227   //   separator: Separator string
4228   //   array_length: Length of the array.
4229   //   string_length: Sum of string lengths (smi).
4230   //   elements: FixedArray of strings.
4231
4232   // Check that the separator is a flat one-byte string.
4233   __ JumpIfSmi(separator, &bailout);
4234   __ lw(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset));
4235   __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
4236   __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
4237
4238   // Add (separator length times array_length) - separator length to the
4239   // string_length to get the length of the result string. array_length is not
4240   // smi but the other values are, so the result is a smi.
4241   __ lw(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
4242   __ Subu(string_length, string_length, Operand(scratch1));
4243   __ Mul(scratch3, scratch2, array_length, scratch1);
4244   // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
4245   // zero.
4246   __ Branch(&bailout, ne, scratch3, Operand(zero_reg));
4247   __ And(scratch3, scratch2, Operand(0x80000000));
4248   __ Branch(&bailout, ne, scratch3, Operand(zero_reg));
4249   __ AdduAndCheckForOverflow(string_length, string_length, scratch2, scratch3);
4250   __ BranchOnOverflow(&bailout, scratch3);
4251   __ SmiUntag(string_length);
4252
4253   // Get first element in the array to free up the elements register to be used
4254   // for the result.
4255   __ Addu(element,
4256           elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4257   result = elements;  // End of live range for elements.
4258   elements = no_reg;
4259   // Live values in registers:
4260   //   element: First array element
4261   //   separator: Separator string
4262   //   string_length: Length of result string (not smi)
4263   //   array_length: Length of the array.
4264   __ AllocateOneByteString(result, string_length, scratch1, scratch2,
4265                            elements_end, &bailout);
4266   // Prepare for looping. Set up elements_end to end of the array. Set
4267   // result_pos to the position of the result where to write the first
4268   // character.
4269   __ sll(elements_end, array_length, kPointerSizeLog2);
4270   __ Addu(elements_end, element, elements_end);
4271   result_pos = array_length;  // End of live range for array_length.
4272   array_length = no_reg;
4273   __ Addu(result_pos,
4274           result,
4275           Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4276
4277   // Check the length of the separator.
4278   __ lw(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
4279   __ li(at, Operand(Smi::FromInt(1)));
4280   __ Branch(&one_char_separator, eq, scratch1, Operand(at));
4281   __ Branch(&long_separator, gt, scratch1, Operand(at));
4282
4283   // Empty separator case.
4284   __ bind(&empty_separator_loop);
4285   // Live values in registers:
4286   //   result_pos: the position to which we are currently copying characters.
4287   //   element: Current array element.
4288   //   elements_end: Array end.
4289
4290   // Copy next array element to the result.
4291   __ lw(string, MemOperand(element));
4292   __ Addu(element, element, kPointerSize);
4293   __ lw(string_length, FieldMemOperand(string, String::kLengthOffset));
4294   __ SmiUntag(string_length);
4295   __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
4296   __ CopyBytes(string, result_pos, string_length, scratch1);
4297   // End while (element < elements_end).
4298   __ Branch(&empty_separator_loop, lt, element, Operand(elements_end));
4299   DCHECK(result.is(v0));
4300   __ Branch(&done);
4301
4302   // One-character separator case.
4303   __ bind(&one_char_separator);
4304   // Replace separator with its one-byte character value.
4305   __ lbu(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
4306   // Jump into the loop after the code that copies the separator, so the first
4307   // element is not preceded by a separator.
4308   __ jmp(&one_char_separator_loop_entry);
4309
4310   __ bind(&one_char_separator_loop);
4311   // Live values in registers:
4312   //   result_pos: the position to which we are currently copying characters.
4313   //   element: Current array element.
4314   //   elements_end: Array end.
4315   //   separator: Single separator one-byte char (in lower byte).
4316
4317   // Copy the separator character to the result.
4318   __ sb(separator, MemOperand(result_pos));
4319   __ Addu(result_pos, result_pos, 1);
4320
4321   // Copy next array element to the result.
4322   __ bind(&one_char_separator_loop_entry);
4323   __ lw(string, MemOperand(element));
4324   __ Addu(element, element, kPointerSize);
4325   __ lw(string_length, FieldMemOperand(string, String::kLengthOffset));
4326   __ SmiUntag(string_length);
4327   __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
4328   __ CopyBytes(string, result_pos, string_length, scratch1);
4329   // End while (element < elements_end).
4330   __ Branch(&one_char_separator_loop, lt, element, Operand(elements_end));
4331   DCHECK(result.is(v0));
4332   __ Branch(&done);
4333
4334   // Long separator case (separator is more than one character). Entry is at the
4335   // label long_separator below.
4336   __ bind(&long_separator_loop);
4337   // Live values in registers:
4338   //   result_pos: the position to which we are currently copying characters.
4339   //   element: Current array element.
4340   //   elements_end: Array end.
4341   //   separator: Separator string.
4342
4343   // Copy the separator to the result.
4344   __ lw(string_length, FieldMemOperand(separator, String::kLengthOffset));
4345   __ SmiUntag(string_length);
4346   __ Addu(string,
4347           separator,
4348           Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4349   __ CopyBytes(string, result_pos, string_length, scratch1);
4350
4351   __ bind(&long_separator);
4352   __ lw(string, MemOperand(element));
4353   __ Addu(element, element, kPointerSize);
4354   __ lw(string_length, FieldMemOperand(string, String::kLengthOffset));
4355   __ SmiUntag(string_length);
4356   __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag);
4357   __ CopyBytes(string, result_pos, string_length, scratch1);
4358   // End while (element < elements_end).
4359   __ Branch(&long_separator_loop, lt, element, Operand(elements_end));
4360   DCHECK(result.is(v0));
4361   __ Branch(&done);
4362
4363   __ bind(&bailout);
4364   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
4365   __ bind(&done);
4366   context()->Plug(v0);
4367 }
4368
4369
4370 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
4371   DCHECK(expr->arguments()->length() == 0);
4372   ExternalReference debug_is_active =
4373       ExternalReference::debug_is_active_address(isolate());
4374   __ li(at, Operand(debug_is_active));
4375   __ lb(v0, MemOperand(at));
4376   __ SmiTag(v0);
4377   context()->Plug(v0);
4378 }
4379
4380
4381 void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
4382   ZoneList<Expression*>* args = expr->arguments();
4383   DCHECK_EQ(2, args->length());
4384   VisitForStackValue(args->at(0));
4385   VisitForStackValue(args->at(1));
4386
4387   Label runtime, done;
4388
4389   __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &runtime, TAG_OBJECT);
4390   __ lw(a1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
4391   __ lw(a1, FieldMemOperand(a1, GlobalObject::kNativeContextOffset));
4392   __ lw(a1, ContextOperand(a1, Context::ITERATOR_RESULT_MAP_INDEX));
4393   __ Pop(a2, a3);
4394   __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex);
4395   __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
4396   __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset));
4397   __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset));
4398   __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset));
4399   __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset));
4400   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
4401   __ jmp(&done);
4402
4403   __ bind(&runtime);
4404   __ CallRuntime(Runtime::kCreateIterResultObject, 2);
4405
4406   __ bind(&done);
4407   context()->Plug(v0);
4408 }
4409
4410
4411 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4412   // Push undefined as the receiver.
4413   __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
4414   __ push(v0);
4415
4416   __ lw(v0, GlobalObjectOperand());
4417   __ lw(v0, FieldMemOperand(v0, GlobalObject::kNativeContextOffset));
4418   __ lw(v0, ContextOperand(v0, expr->context_index()));
4419 }
4420
4421
4422 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
4423   ZoneList<Expression*>* args = expr->arguments();
4424   int arg_count = args->length();
4425
4426   SetCallPosition(expr, arg_count);
4427   CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
4428   __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
4429   __ CallStub(&stub);
4430 }
4431
4432
4433 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4434   ZoneList<Expression*>* args = expr->arguments();
4435   int arg_count = args->length();
4436
4437   if (expr->is_jsruntime()) {
4438     Comment cmnt(masm_, "[ CallRuntime");
4439     EmitLoadJSRuntimeFunction(expr);
4440
4441     // Push the target function under the receiver.
4442     __ lw(at, MemOperand(sp, 0));
4443     __ push(at);
4444     __ sw(v0, MemOperand(sp, kPointerSize));
4445
4446     // Push the arguments ("left-to-right").
4447     for (int i = 0; i < arg_count; i++) {
4448       VisitForStackValue(args->at(i));
4449     }
4450
4451     PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
4452     EmitCallJSRuntimeFunction(expr);
4453
4454     // Restore context register.
4455     __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4456
4457     context()->DropAndPlug(1, v0);
4458
4459   } else {
4460     const Runtime::Function* function = expr->function();
4461     switch (function->function_id) {
4462 #define CALL_INTRINSIC_GENERATOR(Name)     \
4463   case Runtime::kInline##Name: {           \
4464     Comment cmnt(masm_, "[ Inline" #Name); \
4465     return Emit##Name(expr);               \
4466   }
4467       FOR_EACH_FULL_CODE_INTRINSIC(CALL_INTRINSIC_GENERATOR)
4468 #undef CALL_INTRINSIC_GENERATOR
4469       default: {
4470         Comment cmnt(masm_, "[ CallRuntime for unhandled intrinsic");
4471         // Push the arguments ("left-to-right").
4472         for (int i = 0; i < arg_count; i++) {
4473           VisitForStackValue(args->at(i));
4474         }
4475
4476         // Call the C runtime function.
4477         PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
4478         __ CallRuntime(expr->function(), arg_count);
4479         context()->Plug(v0);
4480       }
4481     }
4482   }
4483 }
4484
4485
4486 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4487   switch (expr->op()) {
4488     case Token::DELETE: {
4489       Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4490       Property* property = expr->expression()->AsProperty();
4491       VariableProxy* proxy = expr->expression()->AsVariableProxy();
4492
4493       if (property != NULL) {
4494         VisitForStackValue(property->obj());
4495         VisitForStackValue(property->key());
4496         __ CallRuntime(is_strict(language_mode())
4497                            ? Runtime::kDeleteProperty_Strict
4498                            : Runtime::kDeleteProperty_Sloppy,
4499                        2);
4500         context()->Plug(v0);
4501       } else if (proxy != NULL) {
4502         Variable* var = proxy->var();
4503         // Delete of an unqualified identifier is disallowed in strict mode but
4504         // "delete this" is allowed.
4505         bool is_this = var->HasThisName(isolate());
4506         DCHECK(is_sloppy(language_mode()) || is_this);
4507         if (var->IsUnallocatedOrGlobalSlot()) {
4508           __ lw(a2, GlobalObjectOperand());
4509           __ li(a1, Operand(var->name()));
4510           __ Push(a2, a1);
4511           __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2);
4512           context()->Plug(v0);
4513         } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4514           // Result of deleting non-global, non-dynamic variables is false.
4515           // The subexpression does not have side effects.
4516           context()->Plug(is_this);
4517         } else {
4518           // Non-global variable.  Call the runtime to try to delete from the
4519           // context where the variable was introduced.
4520           DCHECK(!context_register().is(a2));
4521           __ li(a2, Operand(var->name()));
4522           __ Push(context_register(), a2);
4523           __ CallRuntime(Runtime::kDeleteLookupSlot, 2);
4524           context()->Plug(v0);
4525         }
4526       } else {
4527         // Result of deleting non-property, non-variable reference is true.
4528         // The subexpression may have side effects.
4529         VisitForEffect(expr->expression());
4530         context()->Plug(true);
4531       }
4532       break;
4533     }
4534
4535     case Token::VOID: {
4536       Comment cmnt(masm_, "[ UnaryOperation (VOID)");
4537       VisitForEffect(expr->expression());
4538       context()->Plug(Heap::kUndefinedValueRootIndex);
4539       break;
4540     }
4541
4542     case Token::NOT: {
4543       Comment cmnt(masm_, "[ UnaryOperation (NOT)");
4544       if (context()->IsEffect()) {
4545         // Unary NOT has no side effects so it's only necessary to visit the
4546         // subexpression.  Match the optimizing compiler by not branching.
4547         VisitForEffect(expr->expression());
4548       } else if (context()->IsTest()) {
4549         const TestContext* test = TestContext::cast(context());
4550         // The labels are swapped for the recursive call.
4551         VisitForControl(expr->expression(),
4552                         test->false_label(),
4553                         test->true_label(),
4554                         test->fall_through());
4555         context()->Plug(test->true_label(), test->false_label());
4556       } else {
4557         // We handle value contexts explicitly rather than simply visiting
4558         // for control and plugging the control flow into the context,
4559         // because we need to prepare a pair of extra administrative AST ids
4560         // for the optimizing compiler.
4561         DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
4562         Label materialize_true, materialize_false, done;
4563         VisitForControl(expr->expression(),
4564                         &materialize_false,
4565                         &materialize_true,
4566                         &materialize_true);
4567         __ bind(&materialize_true);
4568         PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
4569         __ LoadRoot(v0, Heap::kTrueValueRootIndex);
4570         if (context()->IsStackValue()) __ push(v0);
4571         __ jmp(&done);
4572         __ bind(&materialize_false);
4573         PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
4574         __ LoadRoot(v0, Heap::kFalseValueRootIndex);
4575         if (context()->IsStackValue()) __ push(v0);
4576         __ bind(&done);
4577       }
4578       break;
4579     }
4580
4581     case Token::TYPEOF: {
4582       Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
4583       {
4584         AccumulatorValueContext context(this);
4585         VisitForTypeofValue(expr->expression());
4586       }
4587       __ mov(a3, v0);
4588       TypeofStub typeof_stub(isolate());
4589       __ CallStub(&typeof_stub);
4590       context()->Plug(v0);
4591       break;
4592     }
4593
4594     default:
4595       UNREACHABLE();
4596   }
4597 }
4598
4599
4600 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4601   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
4602
4603   Comment cmnt(masm_, "[ CountOperation");
4604
4605   Property* prop = expr->expression()->AsProperty();
4606   LhsKind assign_type = Property::GetAssignType(prop);
4607
4608   // Evaluate expression and get value.
4609   if (assign_type == VARIABLE) {
4610     DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4611     AccumulatorValueContext context(this);
4612     EmitVariableLoad(expr->expression()->AsVariableProxy());
4613   } else {
4614     // Reserve space for result of postfix operation.
4615     if (expr->is_postfix() && !context()->IsEffect()) {
4616       __ li(at, Operand(Smi::FromInt(0)));
4617       __ push(at);
4618     }
4619     switch (assign_type) {
4620       case NAMED_PROPERTY: {
4621         // Put the object both on the stack and in the register.
4622         VisitForStackValue(prop->obj());
4623         __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
4624         EmitNamedPropertyLoad(prop);
4625         break;
4626       }
4627
4628       case NAMED_SUPER_PROPERTY: {
4629         VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
4630         VisitForAccumulatorValue(
4631             prop->obj()->AsSuperPropertyReference()->home_object());
4632         __ Push(result_register());
4633         const Register scratch = a1;
4634         __ lw(scratch, MemOperand(sp, kPointerSize));
4635         __ Push(scratch, result_register());
4636         EmitNamedSuperPropertyLoad(prop);
4637         break;
4638       }
4639
4640       case KEYED_SUPER_PROPERTY: {
4641         VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
4642         VisitForAccumulatorValue(
4643             prop->obj()->AsSuperPropertyReference()->home_object());
4644         const Register scratch = a1;
4645         const Register scratch1 = t0;
4646         __ Move(scratch, result_register());
4647         VisitForAccumulatorValue(prop->key());
4648         __ Push(scratch, result_register());
4649         __ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
4650         __ Push(scratch1, scratch, result_register());
4651         EmitKeyedSuperPropertyLoad(prop);
4652         break;
4653       }
4654
4655       case KEYED_PROPERTY: {
4656         VisitForStackValue(prop->obj());
4657         VisitForStackValue(prop->key());
4658         __ lw(LoadDescriptor::ReceiverRegister(),
4659               MemOperand(sp, 1 * kPointerSize));
4660         __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
4661         EmitKeyedPropertyLoad(prop);
4662         break;
4663       }
4664
4665       case VARIABLE:
4666         UNREACHABLE();
4667     }
4668   }
4669
4670   // We need a second deoptimization point after loading the value
4671   // in case evaluating the property load my have a side effect.
4672   if (assign_type == VARIABLE) {
4673     PrepareForBailout(expr->expression(), TOS_REG);
4674   } else {
4675     PrepareForBailoutForId(prop->LoadId(), TOS_REG);
4676   }
4677
4678   // Inline smi case if we are in a loop.
4679   Label stub_call, done;
4680   JumpPatchSite patch_site(masm_);
4681
4682   int count_value = expr->op() == Token::INC ? 1 : -1;
4683   __ mov(a0, v0);
4684   if (ShouldInlineSmiCase(expr->op())) {
4685     Label slow;
4686     patch_site.EmitJumpIfNotSmi(v0, &slow);
4687
4688     // Save result for postfix expressions.
4689     if (expr->is_postfix()) {
4690       if (!context()->IsEffect()) {
4691         // Save the result on the stack. If we have a named or keyed property
4692         // we store the result under the receiver that is currently on top
4693         // of the stack.
4694         switch (assign_type) {
4695           case VARIABLE:
4696             __ push(v0);
4697             break;
4698           case NAMED_PROPERTY:
4699             __ sw(v0, MemOperand(sp, kPointerSize));
4700             break;
4701           case NAMED_SUPER_PROPERTY:
4702             __ sw(v0, MemOperand(sp, 2 * kPointerSize));
4703             break;
4704           case KEYED_PROPERTY:
4705             __ sw(v0, MemOperand(sp, 2 * kPointerSize));
4706             break;
4707           case KEYED_SUPER_PROPERTY:
4708             __ sw(v0, MemOperand(sp, 3 * kPointerSize));
4709             break;
4710         }
4711       }
4712     }
4713
4714     Register scratch1 = a1;
4715     Register scratch2 = t0;
4716     __ li(scratch1, Operand(Smi::FromInt(count_value)));
4717     __ AdduAndCheckForOverflow(v0, v0, scratch1, scratch2);
4718     __ BranchOnNoOverflow(&done, scratch2);
4719     // Call stub. Undo operation first.
4720     __ Move(v0, a0);
4721     __ jmp(&stub_call);
4722     __ bind(&slow);
4723   }
4724   if (!is_strong(language_mode())) {
4725     ToNumberStub convert_stub(isolate());
4726     __ CallStub(&convert_stub);
4727     PrepareForBailoutForId(expr->ToNumberId(), TOS_REG);
4728   }
4729
4730   // Save result for postfix expressions.
4731   if (expr->is_postfix()) {
4732     if (!context()->IsEffect()) {
4733       // Save the result on the stack. If we have a named or keyed property
4734       // we store the result under the receiver that is currently on top
4735       // of the stack.
4736       switch (assign_type) {
4737         case VARIABLE:
4738           __ push(v0);
4739           break;
4740         case NAMED_PROPERTY:
4741           __ sw(v0, MemOperand(sp, kPointerSize));
4742           break;
4743         case NAMED_SUPER_PROPERTY:
4744           __ sw(v0, MemOperand(sp, 2 * kPointerSize));
4745           break;
4746         case KEYED_PROPERTY:
4747           __ sw(v0, MemOperand(sp, 2 * kPointerSize));
4748           break;
4749         case KEYED_SUPER_PROPERTY:
4750           __ sw(v0, MemOperand(sp, 3 * kPointerSize));
4751           break;
4752       }
4753     }
4754   }
4755
4756   __ bind(&stub_call);
4757   __ mov(a1, v0);
4758   __ li(a0, Operand(Smi::FromInt(count_value)));
4759
4760   SetExpressionPosition(expr);
4761
4762
4763   Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
4764                                               strength(language_mode())).code();
4765   CallIC(code, expr->CountBinOpFeedbackId());
4766   patch_site.EmitPatchInfo();
4767   __ bind(&done);
4768
4769   if (is_strong(language_mode())) {
4770     PrepareForBailoutForId(expr->ToNumberId(), TOS_REG);
4771   }
4772   // Store the value returned in v0.
4773   switch (assign_type) {
4774     case VARIABLE:
4775       if (expr->is_postfix()) {
4776         { EffectContext context(this);
4777           EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4778                                  Token::ASSIGN, expr->CountSlot());
4779           PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4780           context.Plug(v0);
4781         }
4782         // For all contexts except EffectConstant we have the result on
4783         // top of the stack.
4784         if (!context()->IsEffect()) {
4785           context()->PlugTOS();
4786         }
4787       } else {
4788         EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4789                                Token::ASSIGN, expr->CountSlot());
4790         PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4791         context()->Plug(v0);
4792       }
4793       break;
4794     case NAMED_PROPERTY: {
4795       __ mov(StoreDescriptor::ValueRegister(), result_register());
4796       __ li(StoreDescriptor::NameRegister(),
4797             Operand(prop->key()->AsLiteral()->value()));
4798       __ pop(StoreDescriptor::ReceiverRegister());
4799       if (FLAG_vector_stores) {
4800         EmitLoadStoreICSlot(expr->CountSlot());
4801         CallStoreIC();
4802       } else {
4803         CallStoreIC(expr->CountStoreFeedbackId());
4804       }
4805       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4806       if (expr->is_postfix()) {
4807         if (!context()->IsEffect()) {
4808           context()->PlugTOS();
4809         }
4810       } else {
4811         context()->Plug(v0);
4812       }
4813       break;
4814     }
4815     case NAMED_SUPER_PROPERTY: {
4816       EmitNamedSuperPropertyStore(prop);
4817       if (expr->is_postfix()) {
4818         if (!context()->IsEffect()) {
4819           context()->PlugTOS();
4820         }
4821       } else {
4822         context()->Plug(v0);
4823       }
4824       break;
4825     }
4826     case KEYED_SUPER_PROPERTY: {
4827       EmitKeyedSuperPropertyStore(prop);
4828       if (expr->is_postfix()) {
4829         if (!context()->IsEffect()) {
4830           context()->PlugTOS();
4831         }
4832       } else {
4833         context()->Plug(v0);
4834       }
4835       break;
4836     }
4837     case KEYED_PROPERTY: {
4838       __ mov(StoreDescriptor::ValueRegister(), result_register());
4839       __ Pop(StoreDescriptor::ReceiverRegister(),
4840              StoreDescriptor::NameRegister());
4841       Handle<Code> ic =
4842           CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
4843       if (FLAG_vector_stores) {
4844         EmitLoadStoreICSlot(expr->CountSlot());
4845         CallIC(ic);
4846       } else {
4847         CallIC(ic, expr->CountStoreFeedbackId());
4848       }
4849       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4850       if (expr->is_postfix()) {
4851         if (!context()->IsEffect()) {
4852           context()->PlugTOS();
4853         }
4854       } else {
4855         context()->Plug(v0);
4856       }
4857       break;
4858     }
4859   }
4860 }
4861
4862
4863 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
4864                                                  Expression* sub_expr,
4865                                                  Handle<String> check) {
4866   Label materialize_true, materialize_false;
4867   Label* if_true = NULL;
4868   Label* if_false = NULL;
4869   Label* fall_through = NULL;
4870   context()->PrepareTest(&materialize_true, &materialize_false,
4871                          &if_true, &if_false, &fall_through);
4872
4873   { AccumulatorValueContext context(this);
4874     VisitForTypeofValue(sub_expr);
4875   }
4876   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4877
4878   Factory* factory = isolate()->factory();
4879   if (String::Equals(check, factory->number_string())) {
4880     __ JumpIfSmi(v0, if_true);
4881     __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset));
4882     __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4883     Split(eq, v0, Operand(at), if_true, if_false, fall_through);
4884   } else if (String::Equals(check, factory->string_string())) {
4885     __ JumpIfSmi(v0, if_false);
4886     __ GetObjectType(v0, v0, a1);
4887     Split(lt, a1, Operand(FIRST_NONSTRING_TYPE), if_true, if_false,
4888           fall_through);
4889   } else if (String::Equals(check, factory->symbol_string())) {
4890     __ JumpIfSmi(v0, if_false);
4891     __ GetObjectType(v0, v0, a1);
4892     Split(eq, a1, Operand(SYMBOL_TYPE), if_true, if_false, fall_through);
4893   } else if (String::Equals(check, factory->boolean_string())) {
4894     __ LoadRoot(at, Heap::kTrueValueRootIndex);
4895     __ Branch(if_true, eq, v0, Operand(at));
4896     __ LoadRoot(at, Heap::kFalseValueRootIndex);
4897     Split(eq, v0, Operand(at), if_true, if_false, fall_through);
4898   } else if (String::Equals(check, factory->undefined_string())) {
4899     __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4900     __ Branch(if_true, eq, v0, Operand(at));
4901     __ JumpIfSmi(v0, if_false);
4902     // Check for undetectable objects => true.
4903     __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset));
4904     __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset));
4905     __ And(a1, a1, Operand(1 << Map::kIsUndetectable));
4906     Split(ne, a1, Operand(zero_reg), if_true, if_false, fall_through);
4907   } else if (String::Equals(check, factory->function_string())) {
4908     __ JumpIfSmi(v0, if_false);
4909     __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset));
4910     __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset));
4911     __ And(a1, a1,
4912            Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
4913     Split(eq, a1, Operand(1 << Map::kIsCallable), if_true, if_false,
4914           fall_through);
4915   } else if (String::Equals(check, factory->object_string())) {
4916     __ JumpIfSmi(v0, if_false);
4917     __ LoadRoot(at, Heap::kNullValueRootIndex);
4918     __ Branch(if_true, eq, v0, Operand(at));
4919     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
4920     __ GetObjectType(v0, v0, a1);
4921     __ Branch(if_false, lt, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
4922     // Check for callable or undetectable objects => false.
4923     __ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset));
4924     __ And(a1, a1,
4925            Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
4926     Split(eq, a1, Operand(zero_reg), if_true, if_false, fall_through);
4927 // clang-format off
4928 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type)    \
4929   } else if (String::Equals(check, factory->type##_string())) {  \
4930     __ JumpIfSmi(v0, if_false);                                  \
4931     __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset));      \
4932     __ LoadRoot(at, Heap::k##Type##MapRootIndex);                \
4933     Split(eq, v0, Operand(at), if_true, if_false, fall_through);
4934   SIMD128_TYPES(SIMD128_TYPE)
4935 #undef SIMD128_TYPE
4936     // clang-format on
4937   } else {
4938     if (if_false != fall_through) __ jmp(if_false);
4939   }
4940   context()->Plug(if_true, if_false);
4941 }
4942
4943
4944 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
4945   Comment cmnt(masm_, "[ CompareOperation");
4946   SetExpressionPosition(expr);
4947
4948   // First we try a fast inlined version of the compare when one of
4949   // the operands is a literal.
4950   if (TryLiteralCompare(expr)) return;
4951
4952   // Always perform the comparison for its control flow.  Pack the result
4953   // into the expression's context after the comparison is performed.
4954   Label materialize_true, materialize_false;
4955   Label* if_true = NULL;
4956   Label* if_false = NULL;
4957   Label* fall_through = NULL;
4958   context()->PrepareTest(&materialize_true, &materialize_false,
4959                          &if_true, &if_false, &fall_through);
4960
4961   Token::Value op = expr->op();
4962   VisitForStackValue(expr->left());
4963   switch (op) {
4964     case Token::IN:
4965       VisitForStackValue(expr->right());
4966       __ CallRuntime(Runtime::kHasProperty, 2);
4967       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4968       __ LoadRoot(t0, Heap::kTrueValueRootIndex);
4969       Split(eq, v0, Operand(t0), if_true, if_false, fall_through);
4970       break;
4971
4972     case Token::INSTANCEOF: {
4973       VisitForAccumulatorValue(expr->right());
4974       __ mov(a0, result_register());
4975       __ pop(a1);
4976       InstanceOfStub stub(isolate());
4977       __ CallStub(&stub);
4978       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
4979       __ LoadRoot(at, Heap::kTrueValueRootIndex);
4980       Split(eq, v0, Operand(at), if_true, if_false, fall_through);
4981       break;
4982     }
4983
4984     default: {
4985       VisitForAccumulatorValue(expr->right());
4986       Condition cc = CompareIC::ComputeCondition(op);
4987       __ mov(a0, result_register());
4988       __ pop(a1);
4989
4990       bool inline_smi_code = ShouldInlineSmiCase(op);
4991       JumpPatchSite patch_site(masm_);
4992       if (inline_smi_code) {
4993         Label slow_case;
4994         __ Or(a2, a0, Operand(a1));
4995         patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4996         Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4997         __ bind(&slow_case);
4998       }
4999
5000       Handle<Code> ic = CodeFactory::CompareIC(
5001                             isolate(), op, strength(language_mode())).code();
5002       CallIC(ic, expr->CompareOperationFeedbackId());
5003       patch_site.EmitPatchInfo();
5004       PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
5005       Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
5006     }
5007   }
5008
5009   // Convert the result of the comparison into one expected for this
5010   // expression's context.
5011   context()->Plug(if_true, if_false);
5012 }
5013
5014
5015 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
5016                                               Expression* sub_expr,
5017                                               NilValue nil) {
5018   Label materialize_true, materialize_false;
5019   Label* if_true = NULL;
5020   Label* if_false = NULL;
5021   Label* fall_through = NULL;
5022   context()->PrepareTest(&materialize_true, &materialize_false,
5023                          &if_true, &if_false, &fall_through);
5024
5025   VisitForAccumulatorValue(sub_expr);
5026   PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
5027   __ mov(a0, result_register());
5028   if (expr->op() == Token::EQ_STRICT) {
5029     Heap::RootListIndex nil_value = nil == kNullValue ?
5030         Heap::kNullValueRootIndex :
5031         Heap::kUndefinedValueRootIndex;
5032     __ LoadRoot(a1, nil_value);
5033     Split(eq, a0, Operand(a1), if_true, if_false, fall_through);
5034   } else {
5035     Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
5036     CallIC(ic, expr->CompareOperationFeedbackId());
5037     Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through);
5038   }
5039   context()->Plug(if_true, if_false);
5040 }
5041
5042
5043 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
5044   __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
5045   context()->Plug(v0);
5046 }
5047
5048
5049 Register FullCodeGenerator::result_register() {
5050   return v0;
5051 }
5052
5053
5054 Register FullCodeGenerator::context_register() {
5055   return cp;
5056 }
5057
5058
5059 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
5060   DCHECK_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
5061   __ sw(value, MemOperand(fp, frame_offset));
5062 }
5063
5064
5065 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
5066   __ lw(dst, ContextOperand(cp, context_index));
5067 }
5068
5069
5070 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
5071   Scope* closure_scope = scope()->ClosureScope();
5072   if (closure_scope->is_script_scope() ||
5073       closure_scope->is_module_scope()) {
5074     // Contexts nested in the native context have a canonical empty function
5075     // as their closure, not the anonymous closure containing the global
5076     // code.  Pass a smi sentinel and let the runtime look up the empty
5077     // function.
5078     __ li(at, Operand(Smi::FromInt(0)));
5079   } else if (closure_scope->is_eval_scope()) {
5080     // Contexts created by a call to eval have the same closure as the
5081     // context calling eval, not the anonymous closure containing the eval
5082     // code.  Fetch it from the context.
5083     __ lw(at, ContextOperand(cp, Context::CLOSURE_INDEX));
5084   } else {
5085     DCHECK(closure_scope->is_function_scope());
5086     __ lw(at, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
5087   }
5088   __ push(at);
5089 }
5090
5091
5092 // ----------------------------------------------------------------------------
5093 // Non-local control flow support.
5094
5095 void FullCodeGenerator::EnterFinallyBlock() {
5096   DCHECK(!result_register().is(a1));
5097   // Store result register while executing finally block.
5098   __ push(result_register());
5099   // Cook return address in link register to stack (smi encoded Code* delta).
5100   __ Subu(a1, ra, Operand(masm_->CodeObject()));
5101   DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
5102   STATIC_ASSERT(0 == kSmiTag);
5103   __ Addu(a1, a1, Operand(a1));  // Convert to smi.
5104
5105   // Store result register while executing finally block.
5106   __ push(a1);
5107
5108   // Store pending message while executing finally block.
5109   ExternalReference pending_message_obj =
5110       ExternalReference::address_of_pending_message_obj(isolate());
5111   __ li(at, Operand(pending_message_obj));
5112   __ lw(a1, MemOperand(at));
5113   __ push(a1);
5114
5115   ClearPendingMessage();
5116 }
5117
5118
5119 void FullCodeGenerator::ExitFinallyBlock() {
5120   DCHECK(!result_register().is(a1));
5121   // Restore pending message from stack.
5122   __ pop(a1);
5123   ExternalReference pending_message_obj =
5124       ExternalReference::address_of_pending_message_obj(isolate());
5125   __ li(at, Operand(pending_message_obj));
5126   __ sw(a1, MemOperand(at));
5127
5128   // Restore result register from stack.
5129   __ pop(a1);
5130
5131   // Uncook return address and return.
5132   __ pop(result_register());
5133   DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
5134   __ sra(a1, a1, 1);  // Un-smi-tag value.
5135   __ Addu(at, a1, Operand(masm_->CodeObject()));
5136   __ Jump(at);
5137 }
5138
5139
5140 void FullCodeGenerator::ClearPendingMessage() {
5141   DCHECK(!result_register().is(a1));
5142   ExternalReference pending_message_obj =
5143       ExternalReference::address_of_pending_message_obj(isolate());
5144   __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
5145   __ li(at, Operand(pending_message_obj));
5146   __ sw(a1, MemOperand(at));
5147 }
5148
5149
5150 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) {
5151   DCHECK(FLAG_vector_stores && !slot.IsInvalid());
5152   __ li(VectorStoreICTrampolineDescriptor::SlotRegister(),
5153         Operand(SmiFromSlot(slot)));
5154 }
5155
5156
5157 #undef __
5158
5159
5160 void BackEdgeTable::PatchAt(Code* unoptimized_code,
5161                             Address pc,
5162                             BackEdgeState target_state,
5163                             Code* replacement_code) {
5164   static const int kInstrSize = Assembler::kInstrSize;
5165   Address branch_address = pc - 6 * kInstrSize;
5166   CodePatcher patcher(branch_address, 1);
5167
5168   switch (target_state) {
5169     case INTERRUPT:
5170       // slt at, a3, zero_reg (in case of count based interrupts)
5171       // beq at, zero_reg, ok
5172       // lui t9, <interrupt stub address> upper
5173       // ori t9, <interrupt stub address> lower
5174       // jalr t9
5175       // nop
5176       // ok-label ----- pc_after points here
5177       patcher.masm()->slt(at, a3, zero_reg);
5178       break;
5179     case ON_STACK_REPLACEMENT:
5180     case OSR_AFTER_STACK_CHECK:
5181       // addiu at, zero_reg, 1
5182       // beq at, zero_reg, ok  ;; Not changed
5183       // lui t9, <on-stack replacement address> upper
5184       // ori t9, <on-stack replacement address> lower
5185       // jalr t9  ;; Not changed
5186       // nop  ;; Not changed
5187       // ok-label ----- pc_after points here
5188       patcher.masm()->addiu(at, zero_reg, 1);
5189       break;
5190   }
5191   Address pc_immediate_load_address = pc - 4 * kInstrSize;
5192   // Replace the stack check address in the load-immediate (lui/ori pair)
5193   // with the entry address of the replacement code.
5194   Assembler::set_target_address_at(pc_immediate_load_address,
5195                                    replacement_code->entry());
5196
5197   unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
5198       unoptimized_code, pc_immediate_load_address, replacement_code);
5199 }
5200
5201
5202 BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
5203     Isolate* isolate,
5204     Code* unoptimized_code,
5205     Address pc) {
5206   static const int kInstrSize = Assembler::kInstrSize;
5207   Address branch_address = pc - 6 * kInstrSize;
5208   Address pc_immediate_load_address = pc - 4 * kInstrSize;
5209
5210   DCHECK(Assembler::IsBeq(Assembler::instr_at(pc - 5 * kInstrSize)));
5211   if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) {
5212     DCHECK(reinterpret_cast<uint32_t>(
5213         Assembler::target_address_at(pc_immediate_load_address)) ==
5214            reinterpret_cast<uint32_t>(
5215                isolate->builtins()->InterruptCheck()->entry()));
5216     return INTERRUPT;
5217   }
5218
5219   DCHECK(Assembler::IsAddImmediate(Assembler::instr_at(branch_address)));
5220
5221   if (reinterpret_cast<uint32_t>(
5222       Assembler::target_address_at(pc_immediate_load_address)) ==
5223           reinterpret_cast<uint32_t>(
5224               isolate->builtins()->OnStackReplacement()->entry())) {
5225     return ON_STACK_REPLACEMENT;
5226   }
5227
5228   DCHECK(reinterpret_cast<uint32_t>(
5229       Assembler::target_address_at(pc_immediate_load_address)) ==
5230          reinterpret_cast<uint32_t>(
5231              isolate->builtins()->OsrAfterStackCheck()->entry()));
5232   return OSR_AFTER_STACK_CHECK;
5233 }
5234
5235
5236 }  // namespace internal
5237 }  // namespace v8
5238
5239 #endif  // V8_TARGET_ARCH_MIPS