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_IA32
6
7#include "src/code-factory.h"
8#include "src/codegen.h"
9#include "src/deoptimizer.h"
10#include "src/full-codegen/full-codegen.h"
11#include "src/ia32/frames-ia32.h"
12
13namespace v8 {
14namespace internal {
15
16
17#define __ ACCESS_MASM(masm)
18
19
20void Builtins::Generate_Adaptor(MacroAssembler* masm,
21                                CFunctionId id,
22                                BuiltinExtraArguments extra_args) {
23  // ----------- S t a t e -------------
24  //  -- eax                : number of arguments excluding receiver
25  //  -- edi                : target
26  //  -- edx                : new.target
27  //  -- esp[0]             : return address
28  //  -- esp[4]             : last argument
29  //  -- ...
30  //  -- esp[4 * argc]      : first argument
31  //  -- esp[4 * (argc +1)] : receiver
32  // -----------------------------------
33  __ AssertFunction(edi);
34
35  // Make sure we operate in the context of the called function (for example
36  // ConstructStubs implemented in C++ will be run in the context of the caller
37  // instead of the callee, due to the way that [[Construct]] is defined for
38  // ordinary functions).
39  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
40
41  // Insert extra arguments.
42  int num_extra_args = 0;
43  if (extra_args != BuiltinExtraArguments::kNone) {
44    __ PopReturnAddressTo(ecx);
45    if (extra_args & BuiltinExtraArguments::kTarget) {
46      ++num_extra_args;
47      __ Push(edi);
48    }
49    if (extra_args & BuiltinExtraArguments::kNewTarget) {
50      ++num_extra_args;
51      __ Push(edx);
52    }
53    __ PushReturnAddressFrom(ecx);
54  }
55
56  // JumpToExternalReference expects eax to contain the number of arguments
57  // including the receiver and the extra arguments.
58  __ add(eax, Immediate(num_extra_args + 1));
59
60  __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
61}
62
63
64static void CallRuntimePassFunction(
65    MacroAssembler* masm, Runtime::FunctionId function_id) {
66  // ----------- S t a t e -------------
67  //  -- edx : new target (preserved for callee)
68  //  -- edi : target function (preserved for callee)
69  // -----------------------------------
70
71  FrameScope scope(masm, StackFrame::INTERNAL);
72  // Push a copy of the target function and the new target.
73  __ push(edi);
74  __ push(edx);
75  // Function is also the parameter to the runtime call.
76  __ push(edi);
77
78  __ CallRuntime(function_id, 1);
79  // Restore target function and new target.
80  __ pop(edx);
81  __ pop(edi);
82}
83
84
85static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
86  __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
87  __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kCodeOffset));
88  __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
89  __ jmp(eax);
90}
91
92
93static void GenerateTailCallToReturnedCode(MacroAssembler* masm) {
94  __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
95  __ jmp(eax);
96}
97
98
99void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
100  // Checking whether the queued function is ready for install is optional,
101  // since we come across interrupts and stack checks elsewhere.  However,
102  // not checking may delay installing ready functions, and always checking
103  // would be quite expensive.  A good compromise is to first check against
104  // stack limit as a cue for an interrupt signal.
105  Label ok;
106  ExternalReference stack_limit =
107      ExternalReference::address_of_stack_limit(masm->isolate());
108  __ cmp(esp, Operand::StaticVariable(stack_limit));
109  __ j(above_equal, &ok, Label::kNear);
110
111  CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
112  GenerateTailCallToReturnedCode(masm);
113
114  __ bind(&ok);
115  GenerateTailCallToSharedCode(masm);
116}
117
118
119static void Generate_JSConstructStubHelper(MacroAssembler* masm,
120                                           bool is_api_function,
121                                           bool create_implicit_receiver) {
122  // ----------- S t a t e -------------
123  //  -- eax: number of arguments
124  //  -- edi: constructor function
125  //  -- ebx: allocation site or undefined
126  //  -- edx: new target
127  // -----------------------------------
128
129  // Enter a construct frame.
130  {
131    FrameScope scope(masm, StackFrame::CONSTRUCT);
132
133    // Preserve the incoming parameters on the stack.
134    __ AssertUndefinedOrAllocationSite(ebx);
135    __ push(ebx);
136    __ SmiTag(eax);
137    __ push(eax);
138
139    if (create_implicit_receiver) {
140      __ push(edi);
141      __ push(edx);
142
143      // Try to allocate the object without transitioning into C code. If any of
144      // the preconditions is not met, the code bails out to the runtime call.
145      Label rt_call, allocated;
146      if (FLAG_inline_new) {
147        // Verify that the new target is a JSFunction.
148        __ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx);
149        __ j(not_equal, &rt_call);
150
151        // Load the initial map and verify that it is in fact a map.
152        // edx: new target
153        __ mov(eax,
154               FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset));
155        // Will both indicate a NULL and a Smi
156        __ JumpIfSmi(eax, &rt_call);
157        // edi: constructor
158        // eax: initial map (if proven valid below)
159        __ CmpObjectType(eax, MAP_TYPE, ebx);
160        __ j(not_equal, &rt_call);
161
162        // Fall back to runtime if the expected base constructor and base
163        // constructor differ.
164        __ cmp(edi, FieldOperand(eax, Map::kConstructorOrBackPointerOffset));
165        __ j(not_equal, &rt_call);
166
167        // Check that the constructor is not constructing a JSFunction (see
168        // comments in Runtime_NewObject in runtime.cc). In which case the
169        // initial map's instance type would be JS_FUNCTION_TYPE.
170        // edi: constructor
171        // eax: initial map
172        __ CmpInstanceType(eax, JS_FUNCTION_TYPE);
173        __ j(equal, &rt_call);
174
175        // Now allocate the JSObject on the heap.
176        // edi: constructor
177        // eax: initial map
178        __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
179        __ shl(edi, kPointerSizeLog2);
180
181        __ Allocate(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
182
183        Factory* factory = masm->isolate()->factory();
184
185        // Allocated the JSObject, now initialize the fields.
186        // eax: initial map
187        // ebx: JSObject (not HeapObject tagged - the actual address).
188        // edi: start of next object
189        __ mov(Operand(ebx, JSObject::kMapOffset), eax);
190        __ mov(ecx, factory->empty_fixed_array());
191        __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
192        __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
193        __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
194
195        // Add the object tag to make the JSObject real, so that we can continue
196        // and jump into the continuation code at any time from now on.
197        __ or_(ebx, Immediate(kHeapObjectTag));
198
199        // Fill all the in-object properties with the appropriate filler.
200        // ebx: JSObject (tagged)
201        // ecx: First in-object property of JSObject (not tagged)
202        __ mov(edx, factory->undefined_value());
203
204        if (!is_api_function) {
205          Label no_inobject_slack_tracking;
206
207          // The code below relies on these assumptions.
208          STATIC_ASSERT(Map::kNoSlackTracking == 0);
209          STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
210          // Check if slack tracking is enabled.
211          __ mov(esi, FieldOperand(eax, Map::kBitField3Offset));
212          __ shr(esi, Map::ConstructionCounter::kShift);
213          __ j(zero, &no_inobject_slack_tracking);  // Map::kNoSlackTracking
214          __ push(esi);  // Save allocation count value.
215          // Decrease generous allocation count.
216          __ sub(FieldOperand(eax, Map::kBitField3Offset),
217                 Immediate(1 << Map::ConstructionCounter::kShift));
218
219          // Allocate object with a slack.
220          __ movzx_b(esi, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
221          __ neg(esi);
222          __ lea(esi, Operand(edi, esi, times_pointer_size, 0));
223          // esi: offset of first field after pre-allocated fields
224          if (FLAG_debug_code) {
225            __ cmp(ecx, esi);
226            __ Assert(less_equal,
227                      kUnexpectedNumberOfPreAllocatedPropertyFields);
228          }
229          __ InitializeFieldsWithFiller(ecx, esi, edx);
230
231          // To allow truncation fill the remaining fields with one pointer
232          // filler map.
233          __ mov(edx, factory->one_pointer_filler_map());
234          __ InitializeFieldsWithFiller(ecx, edi, edx);
235
236          __ pop(esi);  // Restore allocation count value before decreasing.
237          __ cmp(esi, Map::kSlackTrackingCounterEnd);
238          __ j(not_equal, &allocated);
239
240          // Push the object to the stack, and then the initial map as
241          // an argument to the runtime call.
242          __ push(ebx);
243          __ push(eax);  // initial map
244          __ CallRuntime(Runtime::kFinalizeInstanceSize);
245          __ pop(ebx);
246
247          // Continue with JSObject being successfully allocated
248          // ebx: JSObject (tagged)
249          __ jmp(&allocated);
250
251          __ bind(&no_inobject_slack_tracking);
252        }
253
254        __ InitializeFieldsWithFiller(ecx, edi, edx);
255
256        // Continue with JSObject being successfully allocated
257        // ebx: JSObject (tagged)
258        __ jmp(&allocated);
259      }
260
261      // Allocate the new receiver object using the runtime call.
262      // edx: new target
263      __ bind(&rt_call);
264      int offset = kPointerSize;
265
266      // Must restore esi (context) and edi (constructor) before calling
267      // runtime.
268      __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
269      __ mov(edi, Operand(esp, offset));
270      __ push(edi);  // constructor function
271      __ push(edx);  // new target
272      __ CallRuntime(Runtime::kNewObject);
273      __ mov(ebx, eax);  // store result in ebx
274
275      // New object allocated.
276      // ebx: newly allocated object
277      __ bind(&allocated);
278
279      // Restore the parameters.
280      __ pop(edx);  // new.target
281      __ pop(edi);  // Constructor function.
282
283      // Retrieve smi-tagged arguments count from the stack.
284      __ mov(eax, Operand(esp, 0));
285    }
286
287    __ SmiUntag(eax);
288
289    if (create_implicit_receiver) {
290      // Push the allocated receiver to the stack. We need two copies
291      // because we may have to return the original one and the calling
292      // conventions dictate that the called function pops the receiver.
293      __ push(ebx);
294      __ push(ebx);
295    } else {
296      __ PushRoot(Heap::kTheHoleValueRootIndex);
297    }
298
299    // Set up pointer to last argument.
300    __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));
301
302    // Copy arguments and receiver to the expression stack.
303    Label loop, entry;
304    __ mov(ecx, eax);
305    __ jmp(&entry);
306    __ bind(&loop);
307    __ push(Operand(ebx, ecx, times_4, 0));
308    __ bind(&entry);
309    __ dec(ecx);
310    __ j(greater_equal, &loop);
311
312    // Call the function.
313    if (is_api_function) {
314      __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
315      Handle<Code> code =
316          masm->isolate()->builtins()->HandleApiCallConstruct();
317      __ call(code, RelocInfo::CODE_TARGET);
318    } else {
319      ParameterCount actual(eax);
320      __ InvokeFunction(edi, edx, actual, CALL_FUNCTION,
321                        CheckDebugStepCallWrapper());
322    }
323
324    // Store offset of return address for deoptimizer.
325    if (create_implicit_receiver && !is_api_function) {
326      masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
327    }
328
329    // Restore context from the frame.
330    __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
331
332    if (create_implicit_receiver) {
333      // If the result is an object (in the ECMA sense), we should get rid
334      // of the receiver and use the result; see ECMA-262 section 13.2.2-7
335      // on page 74.
336      Label use_receiver, exit;
337
338      // If the result is a smi, it is *not* an object in the ECMA sense.
339      __ JumpIfSmi(eax, &use_receiver);
340
341      // If the type of the result (stored in its map) is less than
342      // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
343      __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
344      __ j(above_equal, &exit);
345
346      // Throw away the result of the constructor invocation and use the
347      // on-stack receiver as the result.
348      __ bind(&use_receiver);
349      __ mov(eax, Operand(esp, 0));
350
351      // Restore the arguments count and leave the construct frame. The
352      // arguments count is stored below the receiver.
353      __ bind(&exit);
354      __ mov(ebx, Operand(esp, 1 * kPointerSize));
355    } else {
356      __ mov(ebx, Operand(esp, 0));
357    }
358
359    // Leave construct frame.
360  }
361
362  // Remove caller arguments from the stack and return.
363  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
364  __ pop(ecx);
365  __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver
366  __ push(ecx);
367  if (create_implicit_receiver) {
368    __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
369  }
370  __ ret(0);
371}
372
373
374void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
375  Generate_JSConstructStubHelper(masm, false, true);
376}
377
378
379void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
380  Generate_JSConstructStubHelper(masm, true, true);
381}
382
383
384void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
385  Generate_JSConstructStubHelper(masm, false, false);
386}
387
388
389void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
390  FrameScope scope(masm, StackFrame::INTERNAL);
391  __ push(edi);
392  __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
393}
394
395
396enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt };
397
398
399// Clobbers ecx, edx, edi; preserves all other registers.
400static void Generate_CheckStackOverflow(MacroAssembler* masm,
401                                        IsTagged eax_is_tagged) {
402  // eax   : the number of items to be pushed to the stack
403  //
404  // Check the stack for overflow. We are not trying to catch
405  // interruptions (e.g. debug break and preemption) here, so the "real stack
406  // limit" is checked.
407  Label okay;
408  ExternalReference real_stack_limit =
409      ExternalReference::address_of_real_stack_limit(masm->isolate());
410  __ mov(edi, Operand::StaticVariable(real_stack_limit));
411  // Make ecx the space we have left. The stack might already be overflowed
412  // here which will cause ecx to become negative.
413  __ mov(ecx, esp);
414  __ sub(ecx, edi);
415  // Make edx the space we need for the array when it is unrolled onto the
416  // stack.
417  __ mov(edx, eax);
418  int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0;
419  __ shl(edx, kPointerSizeLog2 - smi_tag);
420  // Check if the arguments will overflow the stack.
421  __ cmp(ecx, edx);
422  __ j(greater, &okay);  // Signed comparison.
423
424  // Out of stack space.
425  __ CallRuntime(Runtime::kThrowStackOverflow);
426
427  __ bind(&okay);
428}
429
430
431static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
432                                             bool is_construct) {
433  ProfileEntryHookStub::MaybeCallEntryHook(masm);
434
435  // Clear the context before we push it when entering the internal frame.
436  __ Move(esi, Immediate(0));
437
438  {
439    FrameScope scope(masm, StackFrame::INTERNAL);
440
441    // Setup the context (we need to use the caller context from the isolate).
442    ExternalReference context_address(Isolate::kContextAddress,
443                                      masm->isolate());
444    __ mov(esi, Operand::StaticVariable(context_address));
445
446    // Load the previous frame pointer (ebx) to access C arguments
447    __ mov(ebx, Operand(ebp, 0));
448
449    // Push the function and the receiver onto the stack.
450    __ push(Operand(ebx, EntryFrameConstants::kFunctionArgOffset));
451    __ push(Operand(ebx, EntryFrameConstants::kReceiverArgOffset));
452
453    // Load the number of arguments and setup pointer to the arguments.
454    __ mov(eax, Operand(ebx, EntryFrameConstants::kArgcOffset));
455    __ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset));
456
457    // Check if we have enough stack space to push all arguments.
458    // Expects argument count in eax. Clobbers ecx, edx, edi.
459    Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt);
460
461    // Copy arguments to the stack in a loop.
462    Label loop, entry;
463    __ Move(ecx, Immediate(0));
464    __ jmp(&entry, Label::kNear);
465    __ bind(&loop);
466    __ mov(edx, Operand(ebx, ecx, times_4, 0));  // push parameter from argv
467    __ push(Operand(edx, 0));  // dereference handle
468    __ inc(ecx);
469    __ bind(&entry);
470    __ cmp(ecx, eax);
471    __ j(not_equal, &loop);
472
473    // Load the previous frame pointer (ebx) to access C arguments
474    __ mov(ebx, Operand(ebp, 0));
475
476    // Get the new.target and function from the frame.
477    __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset));
478    __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset));
479
480    // Invoke the code.
481    Handle<Code> builtin = is_construct
482                               ? masm->isolate()->builtins()->Construct()
483                               : masm->isolate()->builtins()->Call();
484    __ Call(builtin, RelocInfo::CODE_TARGET);
485
486    // Exit the internal frame. Notice that this also removes the empty.
487    // context and the function left on the stack by the code
488    // invocation.
489  }
490  __ ret(kPointerSize);  // Remove receiver.
491}
492
493
494void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
495  Generate_JSEntryTrampolineHelper(masm, false);
496}
497
498
499void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
500  Generate_JSEntryTrampolineHelper(masm, true);
501}
502
503
504// Generate code for entering a JS function with the interpreter.
505// On entry to the function the receiver and arguments have been pushed on the
506// stack left to right.  The actual argument count matches the formal parameter
507// count expected by the function.
508//
509// The live registers are:
510//   o edi: the JS function object being called
511//   o edx: the new target
512//   o esi: our context
513//   o ebp: the caller's frame pointer
514//   o esp: stack pointer (pointing to return address)
515//
516// The function builds a JS frame.  Please see JavaScriptFrameConstants in
517// frames-ia32.h for its layout.
518// TODO(rmcilroy): We will need to include the current bytecode pointer in the
519// frame.
520void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
521  // Open a frame scope to indicate that there is a frame on the stack.  The
522  // MANUAL indicates that the scope shouldn't actually generate code to set up
523  // the frame (that is done below).
524  FrameScope frame_scope(masm, StackFrame::MANUAL);
525  __ push(ebp);  // Caller's frame pointer.
526  __ mov(ebp, esp);
527  __ push(esi);  // Callee's context.
528  __ push(edi);  // Callee's JS function.
529  __ push(edx);  // Callee's new target.
530
531  // Push zero for bytecode array offset.
532  __ push(Immediate(0));
533
534  // Get the bytecode array from the function object and load the pointer to the
535  // first entry into edi (InterpreterBytecodeRegister).
536  __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
537  __ mov(kInterpreterBytecodeArrayRegister,
538         FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset));
539
540  if (FLAG_debug_code) {
541    // Check function data field is actually a BytecodeArray object.
542    __ AssertNotSmi(kInterpreterBytecodeArrayRegister);
543    __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE,
544                     eax);
545    __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
546  }
547
548  // Allocate the local and temporary register file on the stack.
549  {
550    // Load frame size from the BytecodeArray object.
551    __ mov(ebx, FieldOperand(kInterpreterBytecodeArrayRegister,
552                             BytecodeArray::kFrameSizeOffset));
553
554    // Do a stack check to ensure we don't go over the limit.
555    Label ok;
556    __ mov(ecx, esp);
557    __ sub(ecx, ebx);
558    ExternalReference stack_limit =
559        ExternalReference::address_of_real_stack_limit(masm->isolate());
560    __ cmp(ecx, Operand::StaticVariable(stack_limit));
561    __ j(above_equal, &ok);
562    __ CallRuntime(Runtime::kThrowStackOverflow);
563    __ bind(&ok);
564
565    // If ok, push undefined as the initial value for all register file entries.
566    Label loop_header;
567    Label loop_check;
568    __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value()));
569    __ jmp(&loop_check);
570    __ bind(&loop_header);
571    // TODO(rmcilroy): Consider doing more than one push per loop iteration.
572    __ push(eax);
573    // Continue loop if not done.
574    __ bind(&loop_check);
575    __ sub(ebx, Immediate(kPointerSize));
576    __ j(greater_equal, &loop_header);
577  }
578
579  // TODO(rmcilroy): List of things not currently dealt with here but done in
580  // fullcodegen's prologue:
581  //  - Support profiler (specifically profiling_counter).
582  //  - Call ProfileEntryHookStub when isolate has a function_entry_hook.
583  //  - Allow simulator stop operations if FLAG_stop_at is set.
584  //  - Code aging of the BytecodeArray object.
585
586  // Perform stack guard check.
587  {
588    Label ok;
589    ExternalReference stack_limit =
590        ExternalReference::address_of_stack_limit(masm->isolate());
591    __ cmp(esp, Operand::StaticVariable(stack_limit));
592    __ j(above_equal, &ok);
593    __ push(kInterpreterBytecodeArrayRegister);
594    __ CallRuntime(Runtime::kStackGuard);
595    __ pop(kInterpreterBytecodeArrayRegister);
596    __ bind(&ok);
597  }
598
599  // Load accumulator, register file, bytecode offset, dispatch table into
600  // registers.
601  __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
602  __ mov(kInterpreterRegisterFileRegister, ebp);
603  __ add(kInterpreterRegisterFileRegister,
604         Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
605  __ mov(kInterpreterBytecodeOffsetRegister,
606         Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
607  // Since the dispatch table root might be set after builtins are generated,
608  // load directly from the roots table.
609  __ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
610  __ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
611
612  // Push dispatch table as a stack located parameter to the bytecode handler.
613  DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
614  __ push(ebx);
615
616  // Dispatch to the first bytecode handler for the function.
617  __ movzx_b(eax, Operand(kInterpreterBytecodeArrayRegister,
618                          kInterpreterBytecodeOffsetRegister, times_1, 0));
619  __ mov(ebx, Operand(ebx, eax, times_pointer_size, 0));
620  // Restore undefined_value in accumulator (eax)
621  // TODO(rmcilroy): Remove this once we move the dispatch table back into a
622  // register.
623  __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value()));
624  // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
625  // and header removal.
626  __ add(ebx, Immediate(Code::kHeaderSize - kHeapObjectTag));
627  __ call(ebx);
628  __ nop();  // Ensure that return address still counts as interpreter entry
629             // trampoline.
630}
631
632
633void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
634  // TODO(rmcilroy): List of things not currently dealt with here but done in
635  // fullcodegen's EmitReturnSequence.
636  //  - Supporting FLAG_trace for Runtime::TraceExit.
637  //  - Support profiler (specifically decrementing profiling_counter
638  //    appropriately and calling out to HandleInterrupts if necessary).
639
640  // The return value is in accumulator, which is already in rax.
641
642  // Leave the frame (also dropping the register file).
643  __ leave();
644
645  // Drop receiver + arguments and return.
646  __ mov(ebx, FieldOperand(kInterpreterBytecodeArrayRegister,
647                           BytecodeArray::kParameterSizeOffset));
648  __ pop(ecx);
649  __ add(esp, ebx);
650  __ push(ecx);
651  __ ret(0);
652}
653
654
655static void Generate_InterpreterPushArgs(MacroAssembler* masm,
656                                         Register array_limit) {
657  // ----------- S t a t e -------------
658  //  -- ebx : Pointer to the last argument in the args array.
659  //  -- array_limit : Pointer to one before the first argument in the
660  //                   args array.
661  // -----------------------------------
662  Label loop_header, loop_check;
663  __ jmp(&loop_check);
664  __ bind(&loop_header);
665  __ Push(Operand(ebx, 0));
666  __ sub(ebx, Immediate(kPointerSize));
667  __ bind(&loop_check);
668  __ cmp(ebx, array_limit);
669  __ j(greater, &loop_header, Label::kNear);
670}
671
672
673// static
674void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) {
675  // ----------- S t a t e -------------
676  //  -- eax : the number of arguments (not including the receiver)
677  //  -- ebx : the address of the first argument to be pushed. Subsequent
678  //           arguments should be consecutive above this, in the same order as
679  //           they are to be pushed onto the stack.
680  //  -- edi : the target to call (can be any Object).
681  // -----------------------------------
682
683  // Pop return address to allow tail-call after pushing arguments.
684  __ Pop(edx);
685
686  // Find the address of the last argument.
687  __ mov(ecx, eax);
688  __ add(ecx, Immediate(1));  // Add one for receiver.
689  __ shl(ecx, kPointerSizeLog2);
690  __ neg(ecx);
691  __ add(ecx, ebx);
692
693  Generate_InterpreterPushArgs(masm, ecx);
694
695  // Call the target.
696  __ Push(edx);  // Re-push return address.
697  __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
698}
699
700
701// static
702void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
703  // ----------- S t a t e -------------
704  //  -- eax : the number of arguments (not including the receiver)
705  //  -- edx : the new target
706  //  -- edi : the constructor
707  //  -- ebx : the address of the first argument to be pushed. Subsequent
708  //           arguments should be consecutive above this, in the same order as
709  //           they are to be pushed onto the stack.
710  // -----------------------------------
711
712  // Save number of arguments on the stack below where arguments are going
713  // to be pushed.
714  __ mov(ecx, eax);
715  __ neg(ecx);
716  __ mov(Operand(esp, ecx, times_pointer_size, -kPointerSize), eax);
717  __ mov(eax, ecx);
718
719  // Pop return address to allow tail-call after pushing arguments.
720  __ Pop(ecx);
721
722  // Find the address of the last argument.
723  __ shl(eax, kPointerSizeLog2);
724  __ add(eax, ebx);
725
726  // Push padding for receiver.
727  __ Push(Immediate(0));
728
729  Generate_InterpreterPushArgs(masm, eax);
730
731  // Restore number of arguments from slot on stack.
732  __ mov(eax, Operand(esp, -kPointerSize));
733
734  // Re-push return address.
735  __ Push(ecx);
736
737  // Call the constructor with unmodified eax, edi, ebi values.
738  __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
739}
740
741
742static void Generate_InterpreterNotifyDeoptimizedHelper(
743    MacroAssembler* masm, Deoptimizer::BailoutType type) {
744  // Enter an internal frame.
745  {
746    FrameScope scope(masm, StackFrame::INTERNAL);
747    __ Push(kInterpreterAccumulatorRegister);  // Save accumulator register.
748
749    // Pass the deoptimization type to the runtime system.
750    __ Push(Smi::FromInt(static_cast<int>(type)));
751
752    __ CallRuntime(Runtime::kNotifyDeoptimized);
753
754    __ Pop(kInterpreterAccumulatorRegister);  // Restore accumulator register.
755    // Tear down internal frame.
756  }
757
758  // Initialize register file register.
759  __ mov(kInterpreterRegisterFileRegister, ebp);
760  __ add(kInterpreterRegisterFileRegister,
761         Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp));
762
763  // Get the bytecode array pointer from the frame.
764  __ mov(ebx, Operand(kInterpreterRegisterFileRegister,
765                      InterpreterFrameConstants::kFunctionFromRegisterPointer));
766  __ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
767  __ mov(kInterpreterBytecodeArrayRegister,
768         FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset));
769
770  if (FLAG_debug_code) {
771    // Check function data field is actually a BytecodeArray object.
772    __ AssertNotSmi(kInterpreterBytecodeArrayRegister);
773    __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE,
774                     ebx);
775    __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
776  }
777
778  // Get the target bytecode offset from the frame.
779  __ mov(
780      kInterpreterBytecodeOffsetRegister,
781      Operand(kInterpreterRegisterFileRegister,
782              InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer));
783  __ SmiUntag(kInterpreterBytecodeOffsetRegister);
784
785  // Push dispatch table as a stack located parameter to the bytecode handler -
786  // overwrite the state slot (we don't use these for interpreter deopts).
787  __ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
788  __ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
789  DCHECK_EQ(-1, kInterpreterDispatchTableSpillSlot);
790  __ mov(Operand(esp, kPointerSize), ebx);
791
792  // Dispatch to the target bytecode.
793  __ movzx_b(esi, Operand(kInterpreterBytecodeArrayRegister,
794                          kInterpreterBytecodeOffsetRegister, times_1, 0));
795  __ mov(ebx, Operand(ebx, esi, times_pointer_size, 0));
796
797  // Get the context from the frame.
798  // TODO(rmcilroy): Update interpreter frame to expect current context at the
799  // context slot instead of the function context.
800  __ mov(kContextRegister,
801         Operand(kInterpreterRegisterFileRegister,
802                 InterpreterFrameConstants::kContextFromRegisterPointer));
803
804  // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
805  // and header removal.
806  __ add(ebx, Immediate(Code::kHeaderSize - kHeapObjectTag));
807  __ jmp(ebx);
808}
809
810
811void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
812  Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
813}
814
815
816void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
817  Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
818}
819
820
821void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
822  Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
823}
824
825
826void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
827  CallRuntimePassFunction(masm, Runtime::kCompileLazy);
828  GenerateTailCallToReturnedCode(masm);
829}
830
831
832void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
833  CallRuntimePassFunction(masm, Runtime::kCompileOptimized_NotConcurrent);
834  GenerateTailCallToReturnedCode(masm);
835}
836
837
838void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
839  CallRuntimePassFunction(masm, Runtime::kCompileOptimized_Concurrent);
840  GenerateTailCallToReturnedCode(masm);
841}
842
843
844static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
845  // For now, we are relying on the fact that make_code_young doesn't do any
846  // garbage collection which allows us to save/restore the registers without
847  // worrying about which of them contain pointers. We also don't build an
848  // internal frame to make the code faster, since we shouldn't have to do stack
849  // crawls in MakeCodeYoung. This seems a bit fragile.
850
851  // Re-execute the code that was patched back to the young age when
852  // the stub returns.
853  __ sub(Operand(esp, 0), Immediate(5));
854  __ pushad();
855  __ mov(eax, Operand(esp, 8 * kPointerSize));
856  {
857    FrameScope scope(masm, StackFrame::MANUAL);
858    __ PrepareCallCFunction(2, ebx);
859    __ mov(Operand(esp, 1 * kPointerSize),
860           Immediate(ExternalReference::isolate_address(masm->isolate())));
861    __ mov(Operand(esp, 0), eax);
862    __ CallCFunction(
863        ExternalReference::get_make_code_young_function(masm->isolate()), 2);
864  }
865  __ popad();
866  __ ret(0);
867}
868
869#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \
870void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \
871    MacroAssembler* masm) {                                  \
872  GenerateMakeCodeYoungAgainCommon(masm);                    \
873}                                                            \
874void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \
875    MacroAssembler* masm) {                                  \
876  GenerateMakeCodeYoungAgainCommon(masm);                    \
877}
878CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
879#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
880
881
882void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
883  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
884  // that make_code_young doesn't do any garbage collection which allows us to
885  // save/restore the registers without worrying about which of them contain
886  // pointers.
887  __ pushad();
888  __ mov(eax, Operand(esp, 8 * kPointerSize));
889  __ sub(eax, Immediate(Assembler::kCallInstructionLength));
890  {  // NOLINT
891    FrameScope scope(masm, StackFrame::MANUAL);
892    __ PrepareCallCFunction(2, ebx);
893    __ mov(Operand(esp, 1 * kPointerSize),
894           Immediate(ExternalReference::isolate_address(masm->isolate())));
895    __ mov(Operand(esp, 0), eax);
896    __ CallCFunction(
897        ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
898        2);
899  }
900  __ popad();
901
902  // Perform prologue operations usually performed by the young code stub.
903  __ pop(eax);   // Pop return address into scratch register.
904  __ push(ebp);  // Caller's frame pointer.
905  __ mov(ebp, esp);
906  __ push(esi);  // Callee's context.
907  __ push(edi);  // Callee's JS Function.
908  __ push(eax);  // Push return address after frame prologue.
909
910  // Jump to point after the code-age stub.
911  __ ret(0);
912}
913
914
915void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
916  GenerateMakeCodeYoungAgainCommon(masm);
917}
918
919
920void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
921  Generate_MarkCodeAsExecutedOnce(masm);
922}
923
924
925static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
926                                             SaveFPRegsMode save_doubles) {
927  // Enter an internal frame.
928  {
929    FrameScope scope(masm, StackFrame::INTERNAL);
930
931    // Preserve registers across notification, this is important for compiled
932    // stubs that tail call the runtime on deopts passing their parameters in
933    // registers.
934    __ pushad();
935    __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles);
936    __ popad();
937    // Tear down internal frame.
938  }
939
940  __ pop(MemOperand(esp, 0));  // Ignore state offset
941  __ ret(0);  // Return to IC Miss stub, continuation still on stack.
942}
943
944
945void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
946  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
947}
948
949
950void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
951  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
952}
953
954
955static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
956                                             Deoptimizer::BailoutType type) {
957  {
958    FrameScope scope(masm, StackFrame::INTERNAL);
959
960    // Pass deoptimization type to the runtime system.
961    __ push(Immediate(Smi::FromInt(static_cast<int>(type))));
962    __ CallRuntime(Runtime::kNotifyDeoptimized);
963
964    // Tear down internal frame.
965  }
966
967  // Get the full codegen state from the stack and untag it.
968  __ mov(ecx, Operand(esp, 1 * kPointerSize));
969  __ SmiUntag(ecx);
970
971  // Switch on the state.
972  Label not_no_registers, not_tos_eax;
973  __ cmp(ecx, FullCodeGenerator::NO_REGISTERS);
974  __ j(not_equal, &not_no_registers, Label::kNear);
975  __ ret(1 * kPointerSize);  // Remove state.
976
977  __ bind(&not_no_registers);
978  __ mov(eax, Operand(esp, 2 * kPointerSize));
979  __ cmp(ecx, FullCodeGenerator::TOS_REG);
980  __ j(not_equal, &not_tos_eax, Label::kNear);
981  __ ret(2 * kPointerSize);  // Remove state, eax.
982
983  __ bind(&not_tos_eax);
984  __ Abort(kNoCasesLeft);
985}
986
987
988void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
989  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
990}
991
992
993void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
994  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
995}
996
997
998void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
999  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1000}
1001
1002
1003// static
1004void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
1005                                               int field_index) {
1006  // ----------- S t a t e -------------
1007  //  -- esp[0] : return address
1008  //  -- esp[4] : receiver
1009  // -----------------------------------
1010
1011  // 1. Load receiver into eax and check that it's actually a JSDate object.
1012  Label receiver_not_date;
1013  {
1014    __ mov(eax, Operand(esp, kPointerSize));
1015    __ JumpIfSmi(eax, &receiver_not_date);
1016    __ CmpObjectType(eax, JS_DATE_TYPE, ebx);
1017    __ j(not_equal, &receiver_not_date);
1018  }
1019
1020  // 2. Load the specified date field, falling back to the runtime as necessary.
1021  if (field_index == JSDate::kDateValue) {
1022    __ mov(eax, FieldOperand(eax, JSDate::kValueOffset));
1023  } else {
1024    if (field_index < JSDate::kFirstUncachedField) {
1025      Label stamp_mismatch;
1026      __ mov(edx, Operand::StaticVariable(
1027                      ExternalReference::date_cache_stamp(masm->isolate())));
1028      __ cmp(edx, FieldOperand(eax, JSDate::kCacheStampOffset));
1029      __ j(not_equal, &stamp_mismatch, Label::kNear);
1030      __ mov(eax, FieldOperand(
1031                      eax, JSDate::kValueOffset + field_index * kPointerSize));
1032      __ ret(1 * kPointerSize);
1033      __ bind(&stamp_mismatch);
1034    }
1035    FrameScope scope(masm, StackFrame::INTERNAL);
1036    __ PrepareCallCFunction(2, ebx);
1037    __ mov(Operand(esp, 0), eax);
1038    __ mov(Operand(esp, 1 * kPointerSize),
1039           Immediate(Smi::FromInt(field_index)));
1040    __ CallCFunction(
1041        ExternalReference::get_date_field_function(masm->isolate()), 2);
1042  }
1043  __ ret(1 * kPointerSize);
1044
1045  // 3. Raise a TypeError if the receiver is not a date.
1046  __ bind(&receiver_not_date);
1047  {
1048    FrameScope scope(masm, StackFrame::MANUAL);
1049    __ EnterFrame(StackFrame::INTERNAL);
1050    __ CallRuntime(Runtime::kThrowNotDateError);
1051  }
1052}
1053
1054
1055// static
1056void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1057  // ----------- S t a t e -------------
1058  //  -- eax     : argc
1059  //  -- esp[0]  : return address
1060  //  -- esp[4]  : argArray
1061  //  -- esp[8]  : thisArg
1062  //  -- esp[12] : receiver
1063  // -----------------------------------
1064
1065  // 1. Load receiver into edi, argArray into eax (if present), remove all
1066  // arguments from the stack (including the receiver), and push thisArg (if
1067  // present) instead.
1068  {
1069    Label no_arg_array, no_this_arg;
1070    __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1071    __ mov(ebx, edx);
1072    __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1073    __ test(eax, eax);
1074    __ j(zero, &no_this_arg, Label::kNear);
1075    {
1076      __ mov(edx, Operand(esp, eax, times_pointer_size, 0));
1077      __ cmp(eax, Immediate(1));
1078      __ j(equal, &no_arg_array, Label::kNear);
1079      __ mov(ebx, Operand(esp, eax, times_pointer_size, -kPointerSize));
1080      __ bind(&no_arg_array);
1081    }
1082    __ bind(&no_this_arg);
1083    __ PopReturnAddressTo(ecx);
1084    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1085    __ Push(edx);
1086    __ PushReturnAddressFrom(ecx);
1087    __ Move(eax, ebx);
1088  }
1089
1090  // ----------- S t a t e -------------
1091  //  -- eax    : argArray
1092  //  -- edi    : receiver
1093  //  -- esp[0] : return address
1094  //  -- esp[4] : thisArg
1095  // -----------------------------------
1096
1097  // 2. Make sure the receiver is actually callable.
1098  Label receiver_not_callable;
1099  __ JumpIfSmi(edi, &receiver_not_callable, Label::kNear);
1100  __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1101  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
1102  __ j(zero, &receiver_not_callable, Label::kNear);
1103
1104  // 3. Tail call with no arguments if argArray is null or undefined.
1105  Label no_arguments;
1106  __ JumpIfRoot(eax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear);
1107  __ JumpIfRoot(eax, Heap::kUndefinedValueRootIndex, &no_arguments,
1108                Label::kNear);
1109
1110  // 4a. Apply the receiver to the given argArray (passing undefined for
1111  // new.target).
1112  __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1113  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1114
1115  // 4b. The argArray is either null or undefined, so we tail call without any
1116  // arguments to the receiver.
1117  __ bind(&no_arguments);
1118  {
1119    __ Set(eax, 0);
1120    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1121  }
1122
1123  // 4c. The receiver is not callable, throw an appropriate TypeError.
1124  __ bind(&receiver_not_callable);
1125  {
1126    __ mov(Operand(esp, kPointerSize), edi);
1127    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1128  }
1129}
1130
1131
1132// static
1133void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
1134  // Stack Layout:
1135  // esp[0]           : Return address
1136  // esp[8]           : Argument n
1137  // esp[16]          : Argument n-1
1138  //  ...
1139  // esp[8 * n]       : Argument 1
1140  // esp[8 * (n + 1)] : Receiver (callable to call)
1141  //
1142  // eax contains the number of arguments, n, not counting the receiver.
1143  //
1144  // 1. Make sure we have at least one argument.
1145  {
1146    Label done;
1147    __ test(eax, eax);
1148    __ j(not_zero, &done, Label::kNear);
1149    __ PopReturnAddressTo(ebx);
1150    __ PushRoot(Heap::kUndefinedValueRootIndex);
1151    __ PushReturnAddressFrom(ebx);
1152    __ inc(eax);
1153    __ bind(&done);
1154  }
1155
1156  // 2. Get the callable to call (passed as receiver) from the stack.
1157  __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1158
1159  // 3. Shift arguments and return address one slot down on the stack
1160  //    (overwriting the original receiver).  Adjust argument count to make
1161  //    the original first argument the new receiver.
1162  {
1163    Label loop;
1164    __ mov(ecx, eax);
1165    __ bind(&loop);
1166    __ mov(ebx, Operand(esp, ecx, times_pointer_size, 0));
1167    __ mov(Operand(esp, ecx, times_pointer_size, kPointerSize), ebx);
1168    __ dec(ecx);
1169    __ j(not_sign, &loop);  // While non-negative (to copy return address).
1170    __ pop(ebx);            // Discard copy of return address.
1171    __ dec(eax);  // One fewer argument (first argument is new receiver).
1172  }
1173
1174  // 4. Call the callable.
1175  __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1176}
1177
1178
1179void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1180  // ----------- S t a t e -------------
1181  //  -- eax     : argc
1182  //  -- esp[0]  : return address
1183  //  -- esp[4]  : argumentsList
1184  //  -- esp[8]  : thisArgument
1185  //  -- esp[12] : target
1186  //  -- esp[16] : receiver
1187  // -----------------------------------
1188
1189  // 1. Load target into edi (if present), argumentsList into eax (if present),
1190  // remove all arguments from the stack (including the receiver), and push
1191  // thisArgument (if present) instead.
1192  {
1193    Label done;
1194    __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
1195    __ mov(edx, edi);
1196    __ mov(ebx, edi);
1197    __ cmp(eax, Immediate(1));
1198    __ j(below, &done, Label::kNear);
1199    __ mov(edi, Operand(esp, eax, times_pointer_size, -0 * kPointerSize));
1200    __ j(equal, &done, Label::kNear);
1201    __ mov(edx, Operand(esp, eax, times_pointer_size, -1 * kPointerSize));
1202    __ cmp(eax, Immediate(3));
1203    __ j(below, &done, Label::kNear);
1204    __ mov(ebx, Operand(esp, eax, times_pointer_size, -2 * kPointerSize));
1205    __ bind(&done);
1206    __ PopReturnAddressTo(ecx);
1207    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1208    __ Push(edx);
1209    __ PushReturnAddressFrom(ecx);
1210    __ Move(eax, ebx);
1211  }
1212
1213  // ----------- S t a t e -------------
1214  //  -- eax    : argumentsList
1215  //  -- edi    : target
1216  //  -- esp[0] : return address
1217  //  -- esp[4] : thisArgument
1218  // -----------------------------------
1219
1220  // 2. Make sure the target is actually callable.
1221  Label target_not_callable;
1222  __ JumpIfSmi(edi, &target_not_callable, Label::kNear);
1223  __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1224  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
1225  __ j(zero, &target_not_callable, Label::kNear);
1226
1227  // 3a. Apply the target to the given argumentsList (passing undefined for
1228  // new.target).
1229  __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1230  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1231
1232  // 3b. The target is not callable, throw an appropriate TypeError.
1233  __ bind(&target_not_callable);
1234  {
1235    __ mov(Operand(esp, kPointerSize), edi);
1236    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1237  }
1238}
1239
1240
1241void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1242  // ----------- S t a t e -------------
1243  //  -- eax     : argc
1244  //  -- esp[0]  : return address
1245  //  -- esp[4]  : new.target (optional)
1246  //  -- esp[8]  : argumentsList
1247  //  -- esp[12] : target
1248  //  -- esp[16] : receiver
1249  // -----------------------------------
1250
1251  // 1. Load target into edi (if present), argumentsList into eax (if present),
1252  // new.target into edx (if present, otherwise use target), remove all
1253  // arguments from the stack (including the receiver), and push thisArgument
1254  // (if present) instead.
1255  {
1256    Label done;
1257    __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
1258    __ mov(edx, edi);
1259    __ mov(ebx, edi);
1260    __ cmp(eax, Immediate(1));
1261    __ j(below, &done, Label::kNear);
1262    __ mov(edi, Operand(esp, eax, times_pointer_size, -0 * kPointerSize));
1263    __ mov(edx, edi);
1264    __ j(equal, &done, Label::kNear);
1265    __ mov(ebx, Operand(esp, eax, times_pointer_size, -1 * kPointerSize));
1266    __ cmp(eax, Immediate(3));
1267    __ j(below, &done, Label::kNear);
1268    __ mov(edx, Operand(esp, eax, times_pointer_size, -2 * kPointerSize));
1269    __ bind(&done);
1270    __ PopReturnAddressTo(ecx);
1271    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1272    __ PushRoot(Heap::kUndefinedValueRootIndex);
1273    __ PushReturnAddressFrom(ecx);
1274    __ Move(eax, ebx);
1275  }
1276
1277  // ----------- S t a t e -------------
1278  //  -- eax    : argumentsList
1279  //  -- edx    : new.target
1280  //  -- edi    : target
1281  //  -- esp[0] : return address
1282  //  -- esp[4] : receiver (undefined)
1283  // -----------------------------------
1284
1285  // 2. Make sure the target is actually a constructor.
1286  Label target_not_constructor;
1287  __ JumpIfSmi(edi, &target_not_constructor, Label::kNear);
1288  __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1289  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
1290  __ j(zero, &target_not_constructor, Label::kNear);
1291
1292  // 3. Make sure the target is actually a constructor.
1293  Label new_target_not_constructor;
1294  __ JumpIfSmi(edx, &new_target_not_constructor, Label::kNear);
1295  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
1296  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
1297  __ j(zero, &new_target_not_constructor, Label::kNear);
1298
1299  // 4a. Construct the target with the given new.target and argumentsList.
1300  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1301
1302  // 4b. The target is not a constructor, throw an appropriate TypeError.
1303  __ bind(&target_not_constructor);
1304  {
1305    __ mov(Operand(esp, kPointerSize), edi);
1306    __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
1307  }
1308
1309  // 4c. The new.target is not a constructor, throw an appropriate TypeError.
1310  __ bind(&new_target_not_constructor);
1311  {
1312    __ mov(Operand(esp, kPointerSize), edx);
1313    __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
1314  }
1315}
1316
1317
1318void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
1319  // ----------- S t a t e -------------
1320  //  -- eax : argc
1321  //  -- esp[0] : return address
1322  //  -- esp[4] : last argument
1323  // -----------------------------------
1324  Label generic_array_code;
1325
1326  // Get the InternalArray function.
1327  __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi);
1328
1329  if (FLAG_debug_code) {
1330    // Initial map for the builtin InternalArray function should be a map.
1331    __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1332    // Will both indicate a NULL and a Smi.
1333    __ test(ebx, Immediate(kSmiTagMask));
1334    __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction);
1335    __ CmpObjectType(ebx, MAP_TYPE, ecx);
1336    __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction);
1337  }
1338
1339  // Run the native code for the InternalArray function called as a normal
1340  // function.
1341  // tail call a stub
1342  InternalArrayConstructorStub stub(masm->isolate());
1343  __ TailCallStub(&stub);
1344}
1345
1346
1347void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
1348  // ----------- S t a t e -------------
1349  //  -- eax : argc
1350  //  -- esp[0] : return address
1351  //  -- esp[4] : last argument
1352  // -----------------------------------
1353  Label generic_array_code;
1354
1355  // Get the Array function.
1356  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi);
1357  __ mov(edx, edi);
1358
1359  if (FLAG_debug_code) {
1360    // Initial map for the builtin Array function should be a map.
1361    __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1362    // Will both indicate a NULL and a Smi.
1363    __ test(ebx, Immediate(kSmiTagMask));
1364    __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction);
1365    __ CmpObjectType(ebx, MAP_TYPE, ecx);
1366    __ Assert(equal, kUnexpectedInitialMapForArrayFunction);
1367  }
1368
1369  // Run the native code for the Array function called as a normal function.
1370  // tail call a stub
1371  __ mov(ebx, masm->isolate()->factory()->undefined_value());
1372  ArrayConstructorStub stub(masm->isolate());
1373  __ TailCallStub(&stub);
1374}
1375
1376
1377// static
1378void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
1379  // ----------- S t a t e -------------
1380  //  -- eax                 : number of arguments
1381  //  -- edi                 : constructor function
1382  //  -- esp[0]              : return address
1383  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1384  //  -- esp[(argc + 1) * 4] : receiver
1385  // -----------------------------------
1386
1387  // 1. Load the first argument into eax and get rid of the rest (including the
1388  // receiver).
1389  Label no_arguments;
1390  {
1391    __ test(eax, eax);
1392    __ j(zero, &no_arguments, Label::kNear);
1393    __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1394    __ PopReturnAddressTo(ecx);
1395    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1396    __ PushReturnAddressFrom(ecx);
1397    __ mov(eax, ebx);
1398  }
1399
1400  // 2a. Convert the first argument to a number.
1401  ToNumberStub stub(masm->isolate());
1402  __ TailCallStub(&stub);
1403
1404  // 2b. No arguments, return +0 (already in eax).
1405  __ bind(&no_arguments);
1406  __ ret(1 * kPointerSize);
1407}
1408
1409
1410// static
1411void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
1412  // ----------- S t a t e -------------
1413  //  -- eax                 : number of arguments
1414  //  -- edi                 : constructor function
1415  //  -- edx                 : new target
1416  //  -- esp[0]              : return address
1417  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1418  //  -- esp[(argc + 1) * 4] : receiver
1419  // -----------------------------------
1420
1421  // 1. Make sure we operate in the context of the called function.
1422  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1423
1424  // 2. Load the first argument into ebx and get rid of the rest (including the
1425  // receiver).
1426  {
1427    Label no_arguments, done;
1428    __ test(eax, eax);
1429    __ j(zero, &no_arguments, Label::kNear);
1430    __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1431    __ jmp(&done, Label::kNear);
1432    __ bind(&no_arguments);
1433    __ Move(ebx, Smi::FromInt(0));
1434    __ bind(&done);
1435    __ PopReturnAddressTo(ecx);
1436    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1437    __ PushReturnAddressFrom(ecx);
1438  }
1439
1440  // 3. Make sure ebx is a number.
1441  {
1442    Label done_convert;
1443    __ JumpIfSmi(ebx, &done_convert);
1444    __ CompareRoot(FieldOperand(ebx, HeapObject::kMapOffset),
1445                   Heap::kHeapNumberMapRootIndex);
1446    __ j(equal, &done_convert);
1447    {
1448      FrameScope scope(masm, StackFrame::INTERNAL);
1449      __ Push(edi);
1450      __ Push(edx);
1451      __ Move(eax, ebx);
1452      ToNumberStub stub(masm->isolate());
1453      __ CallStub(&stub);
1454      __ Move(ebx, eax);
1455      __ Pop(edx);
1456      __ Pop(edi);
1457    }
1458    __ bind(&done_convert);
1459  }
1460
1461  // 4. Check if new target and constructor differ.
1462  Label new_object;
1463  __ cmp(edx, edi);
1464  __ j(not_equal, &new_object);
1465
1466  // 5. Allocate a JSValue wrapper for the number.
1467  __ AllocateJSValue(eax, edi, ebx, ecx, &new_object);
1468  __ Ret();
1469
1470  // 6. Fallback to the runtime to create new object.
1471  __ bind(&new_object);
1472  {
1473    FrameScope scope(masm, StackFrame::INTERNAL);
1474    __ Push(ebx);  // the first argument
1475    __ Push(edi);  // constructor function
1476    __ Push(edx);  // new target
1477    __ CallRuntime(Runtime::kNewObject);
1478    __ Pop(FieldOperand(eax, JSValue::kValueOffset));
1479  }
1480  __ Ret();
1481}
1482
1483
1484// static
1485void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
1486  // ----------- S t a t e -------------
1487  //  -- eax                 : number of arguments
1488  //  -- edi                 : constructor function
1489  //  -- esp[0]              : return address
1490  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1491  //  -- esp[(argc + 1) * 4] : receiver
1492  // -----------------------------------
1493
1494  // 1. Load the first argument into eax and get rid of the rest (including the
1495  // receiver).
1496  Label no_arguments;
1497  {
1498    __ test(eax, eax);
1499    __ j(zero, &no_arguments, Label::kNear);
1500    __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1501    __ PopReturnAddressTo(ecx);
1502    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1503    __ PushReturnAddressFrom(ecx);
1504    __ mov(eax, ebx);
1505  }
1506
1507  // 2a. At least one argument, return eax if it's a string, otherwise
1508  // dispatch to appropriate conversion.
1509  Label to_string, symbol_descriptive_string;
1510  {
1511    __ JumpIfSmi(eax, &to_string, Label::kNear);
1512    STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
1513    __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
1514    __ j(above, &to_string, Label::kNear);
1515    __ j(equal, &symbol_descriptive_string, Label::kNear);
1516    __ Ret();
1517  }
1518
1519  // 2b. No arguments, return the empty string (and pop the receiver).
1520  __ bind(&no_arguments);
1521  {
1522    __ LoadRoot(eax, Heap::kempty_stringRootIndex);
1523    __ ret(1 * kPointerSize);
1524  }
1525
1526  // 3a. Convert eax to a string.
1527  __ bind(&to_string);
1528  {
1529    ToStringStub stub(masm->isolate());
1530    __ TailCallStub(&stub);
1531  }
1532
1533  // 3b. Convert symbol in eax to a string.
1534  __ bind(&symbol_descriptive_string);
1535  {
1536    __ PopReturnAddressTo(ecx);
1537    __ Push(eax);
1538    __ PushReturnAddressFrom(ecx);
1539    __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
1540  }
1541}
1542
1543
1544// static
1545void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
1546  // ----------- S t a t e -------------
1547  //  -- eax                 : number of arguments
1548  //  -- edi                 : constructor function
1549  //  -- edx                 : new target
1550  //  -- esp[0]              : return address
1551  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1552  //  -- esp[(argc + 1) * 4] : receiver
1553  // -----------------------------------
1554
1555  // 1. Make sure we operate in the context of the called function.
1556  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1557
1558  // 2. Load the first argument into ebx and get rid of the rest (including the
1559  // receiver).
1560  {
1561    Label no_arguments, done;
1562    __ test(eax, eax);
1563    __ j(zero, &no_arguments, Label::kNear);
1564    __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1565    __ jmp(&done, Label::kNear);
1566    __ bind(&no_arguments);
1567    __ LoadRoot(ebx, Heap::kempty_stringRootIndex);
1568    __ bind(&done);
1569    __ PopReturnAddressTo(ecx);
1570    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1571    __ PushReturnAddressFrom(ecx);
1572  }
1573
1574  // 3. Make sure ebx is a string.
1575  {
1576    Label convert, done_convert;
1577    __ JumpIfSmi(ebx, &convert, Label::kNear);
1578    __ CmpObjectType(ebx, FIRST_NONSTRING_TYPE, ecx);
1579    __ j(below, &done_convert);
1580    __ bind(&convert);
1581    {
1582      FrameScope scope(masm, StackFrame::INTERNAL);
1583      ToStringStub stub(masm->isolate());
1584      __ Push(edi);
1585      __ Push(edx);
1586      __ Move(eax, ebx);
1587      __ CallStub(&stub);
1588      __ Move(ebx, eax);
1589      __ Pop(edx);
1590      __ Pop(edi);
1591    }
1592    __ bind(&done_convert);
1593  }
1594
1595  // 4. Check if new target and constructor differ.
1596  Label new_object;
1597  __ cmp(edx, edi);
1598  __ j(not_equal, &new_object);
1599
1600  // 5. Allocate a JSValue wrapper for the string.
1601  __ AllocateJSValue(eax, edi, ebx, ecx, &new_object);
1602  __ Ret();
1603
1604  // 6. Fallback to the runtime to create new object.
1605  __ bind(&new_object);
1606  {
1607    FrameScope scope(masm, StackFrame::INTERNAL);
1608    __ Push(ebx);  // the first argument
1609    __ Push(edi);  // constructor function
1610    __ Push(edx);  // new target
1611    __ CallRuntime(Runtime::kNewObject);
1612    __ Pop(FieldOperand(eax, JSValue::kValueOffset));
1613  }
1614  __ Ret();
1615}
1616
1617
1618static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
1619                                       Label* stack_overflow) {
1620  // ----------- S t a t e -------------
1621  //  -- eax : actual number of arguments
1622  //  -- ebx : expected number of arguments
1623  //  -- edx : new target (passed through to callee)
1624  // -----------------------------------
1625  // Check the stack for overflow. We are not trying to catch
1626  // interruptions (e.g. debug break and preemption) here, so the "real stack
1627  // limit" is checked.
1628  ExternalReference real_stack_limit =
1629      ExternalReference::address_of_real_stack_limit(masm->isolate());
1630  __ mov(edi, Operand::StaticVariable(real_stack_limit));
1631  // Make ecx the space we have left. The stack might already be overflowed
1632  // here which will cause ecx to become negative.
1633  __ mov(ecx, esp);
1634  __ sub(ecx, edi);
1635  // Make edi the space we need for the array when it is unrolled onto the
1636  // stack.
1637  __ mov(edi, ebx);
1638  __ shl(edi, kPointerSizeLog2);
1639  // Check if the arguments will overflow the stack.
1640  __ cmp(ecx, edi);
1641  __ j(less_equal, stack_overflow);  // Signed comparison.
1642}
1643
1644
1645static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1646  __ push(ebp);
1647  __ mov(ebp, esp);
1648
1649  // Store the arguments adaptor context sentinel.
1650  __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1651
1652  // Push the function on the stack.
1653  __ push(edi);
1654
1655  // Preserve the number of arguments on the stack. Must preserve eax,
1656  // ebx and ecx because these registers are used when copying the
1657  // arguments and the receiver.
1658  STATIC_ASSERT(kSmiTagSize == 1);
1659  __ lea(edi, Operand(eax, eax, times_1, kSmiTag));
1660  __ push(edi);
1661}
1662
1663
1664static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1665  // Retrieve the number of arguments from the stack.
1666  __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
1667
1668  // Leave the frame.
1669  __ leave();
1670
1671  // Remove caller arguments from the stack.
1672  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1673  __ pop(ecx);
1674  __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver
1675  __ push(ecx);
1676}
1677
1678
1679// static
1680void Builtins::Generate_Apply(MacroAssembler* masm) {
1681  // ----------- S t a t e -------------
1682  //  -- eax    : argumentsList
1683  //  -- edi    : target
1684  //  -- edx    : new.target (checked to be constructor or undefined)
1685  //  -- esp[0] : return address.
1686  //  -- esp[4] : thisArgument
1687  // -----------------------------------
1688
1689  // Create the list of arguments from the array-like argumentsList.
1690  {
1691    Label create_arguments, create_array, create_runtime, done_create;
1692    __ JumpIfSmi(eax, &create_runtime);
1693
1694    // Load the map of argumentsList into ecx.
1695    __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
1696
1697    // Load native context into ebx.
1698    __ mov(ebx, NativeContextOperand());
1699
1700    // Check if argumentsList is an (unmodified) arguments object.
1701    __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
1702    __ j(equal, &create_arguments);
1703    __ cmp(ecx, ContextOperand(ebx, Context::STRICT_ARGUMENTS_MAP_INDEX));
1704    __ j(equal, &create_arguments);
1705
1706    // Check if argumentsList is a fast JSArray.
1707    __ CmpInstanceType(ecx, JS_ARRAY_TYPE);
1708    __ j(equal, &create_array);
1709
1710    // Ask the runtime to create the list (actually a FixedArray).
1711    __ bind(&create_runtime);
1712    {
1713      FrameScope scope(masm, StackFrame::INTERNAL);
1714      __ Push(edi);
1715      __ Push(edx);
1716      __ Push(eax);
1717      __ CallRuntime(Runtime::kCreateListFromArrayLike);
1718      __ Pop(edx);
1719      __ Pop(edi);
1720      __ mov(ebx, FieldOperand(eax, FixedArray::kLengthOffset));
1721      __ SmiUntag(ebx);
1722    }
1723    __ jmp(&done_create);
1724
1725    // Try to create the list from an arguments object.
1726    __ bind(&create_arguments);
1727    __ mov(ebx,
1728           FieldOperand(eax, JSObject::kHeaderSize +
1729                                 Heap::kArgumentsLengthIndex * kPointerSize));
1730    __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset));
1731    __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
1732    __ j(not_equal, &create_runtime);
1733    __ SmiUntag(ebx);
1734    __ mov(eax, ecx);
1735    __ jmp(&done_create);
1736
1737    // Try to create the list from a JSArray object.
1738    __ bind(&create_array);
1739    __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
1740    __ DecodeField<Map::ElementsKindBits>(ecx);
1741    STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1742    STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1743    STATIC_ASSERT(FAST_ELEMENTS == 2);
1744    __ cmp(ecx, Immediate(FAST_ELEMENTS));
1745    __ j(above, &create_runtime);
1746    __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
1747    __ j(equal, &create_runtime);
1748    __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
1749    __ SmiUntag(ebx);
1750    __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
1751
1752    __ bind(&done_create);
1753  }
1754
1755  // Check for stack overflow.
1756  {
1757    // Check the stack for overflow. We are not trying to catch interruptions
1758    // (i.e. debug break and preemption) here, so check the "real stack limit".
1759    Label done;
1760    ExternalReference real_stack_limit =
1761        ExternalReference::address_of_real_stack_limit(masm->isolate());
1762    __ mov(ecx, Operand::StaticVariable(real_stack_limit));
1763    // Make ecx the space we have left. The stack might already be overflowed
1764    // here which will cause ecx to become negative.
1765    __ neg(ecx);
1766    __ add(ecx, esp);
1767    __ sar(ecx, kPointerSizeLog2);
1768    // Check if the arguments will overflow the stack.
1769    __ cmp(ecx, ebx);
1770    __ j(greater, &done, Label::kNear);  // Signed comparison.
1771    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1772    __ bind(&done);
1773  }
1774
1775  // ----------- S t a t e -------------
1776  //  -- edi    : target
1777  //  -- eax    : args (a FixedArray built from argumentsList)
1778  //  -- ebx    : len (number of elements to push from args)
1779  //  -- edx    : new.target (checked to be constructor or undefined)
1780  //  -- esp[0] : return address.
1781  //  -- esp[4] : thisArgument
1782  // -----------------------------------
1783
1784  // Push arguments onto the stack (thisArgument is already on the stack).
1785  {
1786    __ movd(xmm0, edx);
1787    __ PopReturnAddressTo(edx);
1788    __ Move(ecx, Immediate(0));
1789    Label done, loop;
1790    __ bind(&loop);
1791    __ cmp(ecx, ebx);
1792    __ j(equal, &done, Label::kNear);
1793    __ Push(
1794        FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
1795    __ inc(ecx);
1796    __ jmp(&loop);
1797    __ bind(&done);
1798    __ PushReturnAddressFrom(edx);
1799    __ movd(edx, xmm0);
1800    __ Move(eax, ebx);
1801  }
1802
1803  // Dispatch to Call or Construct depending on whether new.target is undefined.
1804  {
1805    __ CompareRoot(edx, Heap::kUndefinedValueRootIndex);
1806    __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1807    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1808  }
1809}
1810
1811
1812// static
1813void Builtins::Generate_CallFunction(MacroAssembler* masm,
1814                                     ConvertReceiverMode mode) {
1815  // ----------- S t a t e -------------
1816  //  -- eax : the number of arguments (not including the receiver)
1817  //  -- edi : the function to call (checked to be a JSFunction)
1818  // -----------------------------------
1819  __ AssertFunction(edi);
1820
1821  // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1822  // Check that the function is not a "classConstructor".
1823  Label class_constructor;
1824  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1825  __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
1826            SharedFunctionInfo::kClassConstructorBitsWithinByte);
1827  __ j(not_zero, &class_constructor);
1828
1829  // Enter the context of the function; ToObject has to run in the function
1830  // context, and we also need to take the global proxy from the function
1831  // context in case of conversion.
1832  STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
1833                SharedFunctionInfo::kStrictModeByteOffset);
1834  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1835  // We need to convert the receiver for non-native sloppy mode functions.
1836  Label done_convert;
1837  __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
1838            (1 << SharedFunctionInfo::kNativeBitWithinByte) |
1839                (1 << SharedFunctionInfo::kStrictModeBitWithinByte));
1840  __ j(not_zero, &done_convert);
1841  {
1842    // ----------- S t a t e -------------
1843    //  -- eax : the number of arguments (not including the receiver)
1844    //  -- edx : the shared function info.
1845    //  -- edi : the function to call (checked to be a JSFunction)
1846    //  -- esi : the function context.
1847    // -----------------------------------
1848
1849    if (mode == ConvertReceiverMode::kNullOrUndefined) {
1850      // Patch receiver to global proxy.
1851      __ LoadGlobalProxy(ecx);
1852    } else {
1853      Label convert_to_object, convert_receiver;
1854      __ mov(ecx, Operand(esp, eax, times_pointer_size, kPointerSize));
1855      __ JumpIfSmi(ecx, &convert_to_object, Label::kNear);
1856      STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1857      __ CmpObjectType(ecx, FIRST_JS_RECEIVER_TYPE, ebx);
1858      __ j(above_equal, &done_convert);
1859      if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
1860        Label convert_global_proxy;
1861        __ JumpIfRoot(ecx, Heap::kUndefinedValueRootIndex,
1862                      &convert_global_proxy, Label::kNear);
1863        __ JumpIfNotRoot(ecx, Heap::kNullValueRootIndex, &convert_to_object,
1864                         Label::kNear);
1865        __ bind(&convert_global_proxy);
1866        {
1867          // Patch receiver to global proxy.
1868          __ LoadGlobalProxy(ecx);
1869        }
1870        __ jmp(&convert_receiver);
1871      }
1872      __ bind(&convert_to_object);
1873      {
1874        // Convert receiver using ToObject.
1875        // TODO(bmeurer): Inline the allocation here to avoid building the frame
1876        // in the fast case? (fall back to AllocateInNewSpace?)
1877        FrameScope scope(masm, StackFrame::INTERNAL);
1878        __ SmiTag(eax);
1879        __ Push(eax);
1880        __ Push(edi);
1881        __ mov(eax, ecx);
1882        ToObjectStub stub(masm->isolate());
1883        __ CallStub(&stub);
1884        __ mov(ecx, eax);
1885        __ Pop(edi);
1886        __ Pop(eax);
1887        __ SmiUntag(eax);
1888      }
1889      __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1890      __ bind(&convert_receiver);
1891    }
1892    __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ecx);
1893  }
1894  __ bind(&done_convert);
1895
1896  // ----------- S t a t e -------------
1897  //  -- eax : the number of arguments (not including the receiver)
1898  //  -- edx : the shared function info.
1899  //  -- edi : the function to call (checked to be a JSFunction)
1900  //  -- esi : the function context.
1901  // -----------------------------------
1902
1903  __ mov(ebx,
1904         FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
1905  __ SmiUntag(ebx);
1906  ParameterCount actual(eax);
1907  ParameterCount expected(ebx);
1908  __ InvokeFunctionCode(edi, no_reg, expected, actual, JUMP_FUNCTION,
1909                        CheckDebugStepCallWrapper());
1910  // The function is a "classConstructor", need to raise an exception.
1911  __ bind(&class_constructor);
1912  {
1913    FrameScope frame(masm, StackFrame::INTERNAL);
1914    __ push(edi);
1915    __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
1916  }
1917}
1918
1919
1920namespace {
1921
1922void Generate_PushBoundArguments(MacroAssembler* masm) {
1923  // ----------- S t a t e -------------
1924  //  -- eax : the number of arguments (not including the receiver)
1925  //  -- edx : new.target (only in case of [[Construct]])
1926  //  -- edi : target (checked to be a JSBoundFunction)
1927  // -----------------------------------
1928
1929  // Load [[BoundArguments]] into ecx and length of that into ebx.
1930  Label no_bound_arguments;
1931  __ mov(ecx, FieldOperand(edi, JSBoundFunction::kBoundArgumentsOffset));
1932  __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
1933  __ SmiUntag(ebx);
1934  __ test(ebx, ebx);
1935  __ j(zero, &no_bound_arguments);
1936  {
1937    // ----------- S t a t e -------------
1938    //  -- eax : the number of arguments (not including the receiver)
1939    //  -- edx : new.target (only in case of [[Construct]])
1940    //  -- edi : target (checked to be a JSBoundFunction)
1941    //  -- ecx : the [[BoundArguments]] (implemented as FixedArray)
1942    //  -- ebx : the number of [[BoundArguments]]
1943    // -----------------------------------
1944
1945    // Reserve stack space for the [[BoundArguments]].
1946    {
1947      Label done;
1948      __ lea(ecx, Operand(ebx, times_pointer_size, 0));
1949      __ sub(esp, ecx);
1950      // Check the stack for overflow. We are not trying to catch interruptions
1951      // (i.e. debug break and preemption) here, so check the "real stack
1952      // limit".
1953      __ CompareRoot(esp, ecx, Heap::kRealStackLimitRootIndex);
1954      __ j(greater, &done, Label::kNear);  // Signed comparison.
1955      // Restore the stack pointer.
1956      __ lea(esp, Operand(esp, ebx, times_pointer_size, 0));
1957      {
1958        FrameScope scope(masm, StackFrame::MANUAL);
1959        __ EnterFrame(StackFrame::INTERNAL);
1960        __ CallRuntime(Runtime::kThrowStackOverflow);
1961      }
1962      __ bind(&done);
1963    }
1964
1965    // Adjust effective number of arguments to include return address.
1966    __ inc(eax);
1967
1968    // Relocate arguments and return address down the stack.
1969    {
1970      Label loop;
1971      __ Set(ecx, 0);
1972      __ lea(ebx, Operand(esp, ebx, times_pointer_size, 0));
1973      __ bind(&loop);
1974      __ movd(xmm0, Operand(ebx, ecx, times_pointer_size, 0));
1975      __ movd(Operand(esp, ecx, times_pointer_size, 0), xmm0);
1976      __ inc(ecx);
1977      __ cmp(ecx, eax);
1978      __ j(less, &loop);
1979    }
1980
1981    // Copy [[BoundArguments]] to the stack (below the arguments).
1982    {
1983      Label loop;
1984      __ mov(ecx, FieldOperand(edi, JSBoundFunction::kBoundArgumentsOffset));
1985      __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
1986      __ SmiUntag(ebx);
1987      __ bind(&loop);
1988      __ dec(ebx);
1989      __ movd(xmm0, FieldOperand(ecx, ebx, times_pointer_size,
1990                                 FixedArray::kHeaderSize));
1991      __ movd(Operand(esp, eax, times_pointer_size, 0), xmm0);
1992      __ lea(eax, Operand(eax, 1));
1993      __ j(greater, &loop);
1994    }
1995
1996    // Adjust effective number of arguments (eax contains the number of
1997    // arguments from the call plus return address plus the number of
1998    // [[BoundArguments]]), so we need to subtract one for the return address.
1999    __ dec(eax);
2000  }
2001  __ bind(&no_bound_arguments);
2002}
2003
2004}  // namespace
2005
2006
2007// static
2008void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) {
2009  // ----------- S t a t e -------------
2010  //  -- eax : the number of arguments (not including the receiver)
2011  //  -- edi : the function to call (checked to be a JSBoundFunction)
2012  // -----------------------------------
2013  __ AssertBoundFunction(edi);
2014
2015  // Patch the receiver to [[BoundThis]].
2016  __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset));
2017  __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx);
2018
2019  // Push the [[BoundArguments]] onto the stack.
2020  Generate_PushBoundArguments(masm);
2021
2022  // Call the [[BoundTargetFunction]] via the Call builtin.
2023  __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2024  __ mov(ecx, Operand::StaticVariable(ExternalReference(
2025                  Builtins::kCall_ReceiverIsAny, masm->isolate())));
2026  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2027  __ jmp(ecx);
2028}
2029
2030
2031// static
2032void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
2033  // ----------- S t a t e -------------
2034  //  -- eax : the number of arguments (not including the receiver)
2035  //  -- edi : the target to call (can be any Object).
2036  // -----------------------------------
2037
2038  Label non_callable, non_function, non_smi;
2039  __ JumpIfSmi(edi, &non_callable);
2040  __ bind(&non_smi);
2041  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2042  __ j(equal, masm->isolate()->builtins()->CallFunction(mode),
2043       RelocInfo::CODE_TARGET);
2044  __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2045  __ j(equal, masm->isolate()->builtins()->CallBoundFunction(),
2046       RelocInfo::CODE_TARGET);
2047  __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2048  __ j(not_equal, &non_function);
2049
2050  // 1. Runtime fallback for Proxy [[Call]].
2051  __ PopReturnAddressTo(ecx);
2052  __ Push(edi);
2053  __ PushReturnAddressFrom(ecx);
2054  // Increase the arguments size to include the pushed function and the
2055  // existing receiver on the stack.
2056  __ add(eax, Immediate(2));
2057  // Tail-call to the runtime.
2058  __ JumpToExternalReference(
2059      ExternalReference(Runtime::kJSProxyCall, masm->isolate()));
2060
2061  // 2. Call to something else, which might have a [[Call]] internal method (if
2062  // not we raise an exception).
2063  __ bind(&non_function);
2064  // Check if target has a [[Call]] internal method.
2065  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
2066  __ j(zero, &non_callable, Label::kNear);
2067  // Overwrite the original receiver with the (original) target.
2068  __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
2069  // Let the "call_as_function_delegate" take care of the rest.
2070  __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, edi);
2071  __ Jump(masm->isolate()->builtins()->CallFunction(
2072              ConvertReceiverMode::kNotNullOrUndefined),
2073          RelocInfo::CODE_TARGET);
2074
2075  // 3. Call to something that is not callable.
2076  __ bind(&non_callable);
2077  {
2078    FrameScope scope(masm, StackFrame::INTERNAL);
2079    __ Push(edi);
2080    __ CallRuntime(Runtime::kThrowCalledNonCallable);
2081  }
2082}
2083
2084
2085// static
2086void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2087  // ----------- S t a t e -------------
2088  //  -- eax : the number of arguments (not including the receiver)
2089  //  -- edx : the new target (checked to be a constructor)
2090  //  -- edi : the constructor to call (checked to be a JSFunction)
2091  // -----------------------------------
2092  __ AssertFunction(edi);
2093
2094  // Calling convention for function specific ConstructStubs require
2095  // ebx to contain either an AllocationSite or undefined.
2096  __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
2097
2098  // Tail call to the function-specific construct stub (still in the caller
2099  // context at this point).
2100  __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2101  __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
2102  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2103  __ jmp(ecx);
2104}
2105
2106
2107// static
2108void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2109  // ----------- S t a t e -------------
2110  //  -- eax : the number of arguments (not including the receiver)
2111  //  -- edx : the new target (checked to be a constructor)
2112  //  -- edi : the constructor to call (checked to be a JSBoundFunction)
2113  // -----------------------------------
2114  __ AssertBoundFunction(edi);
2115
2116  // Push the [[BoundArguments]] onto the stack.
2117  Generate_PushBoundArguments(masm);
2118
2119  // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2120  {
2121    Label done;
2122    __ cmp(edi, edx);
2123    __ j(not_equal, &done, Label::kNear);
2124    __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2125    __ bind(&done);
2126  }
2127
2128  // Construct the [[BoundTargetFunction]] via the Construct builtin.
2129  __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2130  __ mov(ecx, Operand::StaticVariable(
2131                  ExternalReference(Builtins::kConstruct, masm->isolate())));
2132  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2133  __ jmp(ecx);
2134}
2135
2136
2137// static
2138void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2139  // ----------- S t a t e -------------
2140  //  -- eax : the number of arguments (not including the receiver)
2141  //  -- edi : the constructor to call (checked to be a JSProxy)
2142  //  -- edx : the new target (either the same as the constructor or
2143  //           the JSFunction on which new was invoked initially)
2144  // -----------------------------------
2145
2146  // Call into the Runtime for Proxy [[Construct]].
2147  __ PopReturnAddressTo(ecx);
2148  __ Push(edi);
2149  __ Push(edx);
2150  __ PushReturnAddressFrom(ecx);
2151  // Include the pushed new_target, constructor and the receiver.
2152  __ add(eax, Immediate(3));
2153  // Tail-call to the runtime.
2154  __ JumpToExternalReference(
2155      ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2156}
2157
2158
2159// static
2160void Builtins::Generate_Construct(MacroAssembler* masm) {
2161  // ----------- S t a t e -------------
2162  //  -- eax : the number of arguments (not including the receiver)
2163  //  -- edx : the new target (either the same as the constructor or
2164  //           the JSFunction on which new was invoked initially)
2165  //  -- edi : the constructor to call (can be any Object)
2166  // -----------------------------------
2167
2168  // Check if target is a Smi.
2169  Label non_constructor;
2170  __ JumpIfSmi(edi, &non_constructor, Label::kNear);
2171
2172  // Dispatch based on instance type.
2173  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2174  __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2175       RelocInfo::CODE_TARGET);
2176
2177  // Check if target has a [[Construct]] internal method.
2178  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
2179  __ j(zero, &non_constructor, Label::kNear);
2180
2181  // Only dispatch to bound functions after checking whether they are
2182  // constructors.
2183  __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2184  __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2185       RelocInfo::CODE_TARGET);
2186
2187  // Only dispatch to proxies after checking whether they are constructors.
2188  __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2189  __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
2190       RelocInfo::CODE_TARGET);
2191
2192  // Called Construct on an exotic Object with a [[Construct]] internal method.
2193  {
2194    // Overwrite the original receiver with the (original) target.
2195    __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
2196    // Let the "call_as_constructor_delegate" take care of the rest.
2197    __ LoadGlobalFunction(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, edi);
2198    __ Jump(masm->isolate()->builtins()->CallFunction(),
2199            RelocInfo::CODE_TARGET);
2200  }
2201
2202  // Called Construct on an Object that doesn't have a [[Construct]] internal
2203  // method.
2204  __ bind(&non_constructor);
2205  __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2206          RelocInfo::CODE_TARGET);
2207}
2208
2209
2210void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
2211  // ----------- S t a t e -------------
2212  //  -- eax : actual number of arguments
2213  //  -- ebx : expected number of arguments
2214  //  -- edx : new target (passed through to callee)
2215  //  -- edi : function (passed through to callee)
2216  // -----------------------------------
2217
2218  Label invoke, dont_adapt_arguments, stack_overflow;
2219  __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
2220
2221  Label enough, too_few;
2222  __ cmp(eax, ebx);
2223  __ j(less, &too_few);
2224  __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
2225  __ j(equal, &dont_adapt_arguments);
2226
2227  {  // Enough parameters: Actual >= expected.
2228    __ bind(&enough);
2229    EnterArgumentsAdaptorFrame(masm);
2230    ArgumentsAdaptorStackCheck(masm, &stack_overflow);
2231
2232    // Copy receiver and all expected arguments.
2233    const int offset = StandardFrameConstants::kCallerSPOffset;
2234    __ lea(edi, Operand(ebp, eax, times_4, offset));
2235    __ mov(eax, -1);  // account for receiver
2236
2237    Label copy;
2238    __ bind(&copy);
2239    __ inc(eax);
2240    __ push(Operand(edi, 0));
2241    __ sub(edi, Immediate(kPointerSize));
2242    __ cmp(eax, ebx);
2243    __ j(less, &copy);
2244    // eax now contains the expected number of arguments.
2245    __ jmp(&invoke);
2246  }
2247
2248  {  // Too few parameters: Actual < expected.
2249    __ bind(&too_few);
2250
2251    // If the function is strong we need to throw an error.
2252    Label no_strong_error;
2253    __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2254    __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrongModeByteOffset),
2255              1 << SharedFunctionInfo::kStrongModeBitWithinByte);
2256    __ j(equal, &no_strong_error, Label::kNear);
2257
2258    // What we really care about is the required number of arguments.
2259    __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kLengthOffset));
2260    __ SmiUntag(ecx);
2261    __ cmp(eax, ecx);
2262    __ j(greater_equal, &no_strong_error, Label::kNear);
2263
2264    {
2265      FrameScope frame(masm, StackFrame::MANUAL);
2266      EnterArgumentsAdaptorFrame(masm);
2267      __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments);
2268    }
2269
2270    __ bind(&no_strong_error);
2271    EnterArgumentsAdaptorFrame(masm);
2272    ArgumentsAdaptorStackCheck(masm, &stack_overflow);
2273
2274    // Remember expected arguments in ecx.
2275    __ mov(ecx, ebx);
2276
2277    // Copy receiver and all actual arguments.
2278    const int offset = StandardFrameConstants::kCallerSPOffset;
2279    __ lea(edi, Operand(ebp, eax, times_4, offset));
2280    // ebx = expected - actual.
2281    __ sub(ebx, eax);
2282    // eax = -actual - 1
2283    __ neg(eax);
2284    __ sub(eax, Immediate(1));
2285
2286    Label copy;
2287    __ bind(&copy);
2288    __ inc(eax);
2289    __ push(Operand(edi, 0));
2290    __ sub(edi, Immediate(kPointerSize));
2291    __ test(eax, eax);
2292    __ j(not_zero, &copy);
2293
2294    // Fill remaining expected arguments with undefined values.
2295    Label fill;
2296    __ bind(&fill);
2297    __ inc(eax);
2298    __ push(Immediate(masm->isolate()->factory()->undefined_value()));
2299    __ cmp(eax, ebx);
2300    __ j(less, &fill);
2301
2302    // Restore expected arguments.
2303    __ mov(eax, ecx);
2304  }
2305
2306  // Call the entry point.
2307  __ bind(&invoke);
2308  // Restore function pointer.
2309  __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2310  // eax : expected number of arguments
2311  // edx : new target (passed through to callee)
2312  // edi : function (passed through to callee)
2313  __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
2314  __ call(ecx);
2315
2316  // Store offset of return address for deoptimizer.
2317  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
2318
2319  // Leave frame and return.
2320  LeaveArgumentsAdaptorFrame(masm);
2321  __ ret(0);
2322
2323  // -------------------------------------------
2324  // Dont adapt arguments.
2325  // -------------------------------------------
2326  __ bind(&dont_adapt_arguments);
2327  __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
2328  __ jmp(ecx);
2329
2330  __ bind(&stack_overflow);
2331  {
2332    FrameScope frame(masm, StackFrame::MANUAL);
2333    __ CallRuntime(Runtime::kThrowStackOverflow);
2334    __ int3();
2335  }
2336}
2337
2338
2339static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
2340                                    Register function_template_info,
2341                                    Register scratch0, Register scratch1,
2342                                    Label* receiver_check_failed) {
2343  // If there is no signature, return the holder.
2344  __ CompareRoot(FieldOperand(function_template_info,
2345                              FunctionTemplateInfo::kSignatureOffset),
2346                 Heap::kUndefinedValueRootIndex);
2347  Label receiver_check_passed;
2348  __ j(equal, &receiver_check_passed, Label::kNear);
2349
2350  // Walk the prototype chain.
2351  __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
2352  Label prototype_loop_start;
2353  __ bind(&prototype_loop_start);
2354
2355  // Get the constructor, if any.
2356  __ GetMapConstructor(scratch0, scratch0, scratch1);
2357  __ CmpInstanceType(scratch1, JS_FUNCTION_TYPE);
2358  Label next_prototype;
2359  __ j(not_equal, &next_prototype, Label::kNear);
2360
2361  // Get the constructor's signature.
2362  __ mov(scratch0,
2363         FieldOperand(scratch0, JSFunction::kSharedFunctionInfoOffset));
2364  __ mov(scratch0,
2365         FieldOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
2366
2367  // Loop through the chain of inheriting function templates.
2368  Label function_template_loop;
2369  __ bind(&function_template_loop);
2370
2371  // If the signatures match, we have a compatible receiver.
2372  __ cmp(scratch0, FieldOperand(function_template_info,
2373                                FunctionTemplateInfo::kSignatureOffset));
2374  __ j(equal, &receiver_check_passed, Label::kNear);
2375
2376  // If the current type is not a FunctionTemplateInfo, load the next prototype
2377  // in the chain.
2378  __ JumpIfSmi(scratch0, &next_prototype, Label::kNear);
2379  __ CmpObjectType(scratch0, FUNCTION_TEMPLATE_INFO_TYPE, scratch1);
2380  __ j(not_equal, &next_prototype, Label::kNear);
2381
2382  // Otherwise load the parent function template and iterate.
2383  __ mov(scratch0,
2384         FieldOperand(scratch0, FunctionTemplateInfo::kParentTemplateOffset));
2385  __ jmp(&function_template_loop, Label::kNear);
2386
2387  // Load the next prototype.
2388  __ bind(&next_prototype);
2389  __ mov(receiver, FieldOperand(receiver, HeapObject::kMapOffset));
2390  __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset));
2391  // End if the prototype is null or not hidden.
2392  __ CompareRoot(receiver, Heap::kNullValueRootIndex);
2393  __ j(equal, receiver_check_failed);
2394  __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
2395  __ test(FieldOperand(scratch0, Map::kBitField3Offset),
2396          Immediate(Map::IsHiddenPrototype::kMask));
2397  __ j(zero, receiver_check_failed);
2398  // Iterate.
2399  __ jmp(&prototype_loop_start, Label::kNear);
2400
2401  __ bind(&receiver_check_passed);
2402}
2403
2404
2405void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
2406  // ----------- S t a t e -------------
2407  //  -- eax                : number of arguments (not including the receiver)
2408  //  -- edi                : callee
2409  //  -- esi                : context
2410  //  -- esp[0]             : return address
2411  //  -- esp[4]             : last argument
2412  //  -- ...
2413  //  -- esp[eax * 4]       : first argument
2414  //  -- esp[(eax + 1) * 4] : receiver
2415  // -----------------------------------
2416
2417  // Load the FunctionTemplateInfo.
2418  __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2419  __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset));
2420
2421  // Do the compatible receiver check.
2422  Label receiver_check_failed;
2423  __ mov(ecx, Operand(esp, eax, times_pointer_size, kPCOnStackSize));
2424  __ Push(eax);
2425  CompatibleReceiverCheck(masm, ecx, ebx, edx, eax, &receiver_check_failed);
2426  __ Pop(eax);
2427  // Get the callback offset from the FunctionTemplateInfo, and jump to the
2428  // beginning of the code.
2429  __ mov(edx, FieldOperand(ebx, FunctionTemplateInfo::kCallCodeOffset));
2430  __ mov(edx, FieldOperand(edx, CallHandlerInfo::kFastHandlerOffset));
2431  __ add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag));
2432  __ jmp(edx);
2433
2434  // Compatible receiver check failed: pop return address, arguments and
2435  // receiver and throw an Illegal Invocation exception.
2436  __ bind(&receiver_check_failed);
2437  __ Pop(eax);
2438  __ PopReturnAddressTo(ebx);
2439  __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize));
2440  __ add(esp, eax);
2441  __ PushReturnAddressFrom(ebx);
2442  {
2443    FrameScope scope(masm, StackFrame::INTERNAL);
2444    __ TailCallRuntime(Runtime::kThrowIllegalInvocation);
2445  }
2446}
2447
2448
2449void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
2450  // Lookup the function in the JavaScript frame.
2451  __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2452  {
2453    FrameScope scope(masm, StackFrame::INTERNAL);
2454    // Pass function as argument.
2455    __ push(eax);
2456    __ CallRuntime(Runtime::kCompileForOnStackReplacement);
2457  }
2458
2459  Label skip;
2460  // If the code object is null, just return to the unoptimized code.
2461  __ cmp(eax, Immediate(0));
2462  __ j(not_equal, &skip, Label::kNear);
2463  __ ret(0);
2464
2465  __ bind(&skip);
2466
2467  // Load deoptimization data from the code object.
2468  __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag));
2469
2470  // Load the OSR entrypoint offset from the deoptimization data.
2471  __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt(
2472      DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag));
2473  __ SmiUntag(ebx);
2474
2475  // Compute the target address = code_obj + header_size + osr_offset
2476  __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag));
2477
2478  // Overwrite the return address on the stack.
2479  __ mov(Operand(esp, 0), eax);
2480
2481  // And "return" to the OSR entry point of the function.
2482  __ ret(0);
2483}
2484
2485
2486void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
2487  // We check the stack limit as indicator that recompilation might be done.
2488  Label ok;
2489  ExternalReference stack_limit =
2490      ExternalReference::address_of_stack_limit(masm->isolate());
2491  __ cmp(esp, Operand::StaticVariable(stack_limit));
2492  __ j(above_equal, &ok, Label::kNear);
2493  {
2494    FrameScope scope(masm, StackFrame::INTERNAL);
2495    __ CallRuntime(Runtime::kStackGuard);
2496  }
2497  __ jmp(masm->isolate()->builtins()->OnStackReplacement(),
2498         RelocInfo::CODE_TARGET);
2499
2500  __ bind(&ok);
2501  __ ret(0);
2502}
2503
2504#undef __
2505}  // namespace internal
2506}  // namespace v8
2507
2508#endif  // V8_TARGET_ARCH_IA32
2509