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#define __ ACCESS_MASM(masm)
17
18void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
19                                ExitFrameType exit_frame_type) {
20  // ----------- S t a t e -------------
21  //  -- eax                : number of arguments excluding receiver
22  //  -- edi                : target
23  //  -- edx                : new.target
24  //  -- esp[0]             : return address
25  //  -- esp[4]             : last argument
26  //  -- ...
27  //  -- esp[4 * argc]      : first argument
28  //  -- esp[4 * (argc +1)] : receiver
29  // -----------------------------------
30  __ AssertFunction(edi);
31
32  // Make sure we operate in the context of the called function (for example
33  // ConstructStubs implemented in C++ will be run in the context of the caller
34  // instead of the callee, due to the way that [[Construct]] is defined for
35  // ordinary functions).
36  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
37
38  // JumpToExternalReference expects eax to contain the number of arguments
39  // including the receiver and the extra arguments.
40  const int num_extra_args = 3;
41  __ add(eax, Immediate(num_extra_args + 1));
42
43  // Insert extra arguments.
44  __ PopReturnAddressTo(ecx);
45  __ SmiTag(eax);
46  __ Push(eax);
47  __ SmiUntag(eax);
48  __ Push(edi);
49  __ Push(edx);
50  __ PushReturnAddressFrom(ecx);
51
52  __ JumpToExternalReference(ExternalReference(address, masm->isolate()),
53                             exit_frame_type == BUILTIN_EXIT);
54}
55
56static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
57                                           Runtime::FunctionId function_id) {
58  // ----------- S t a t e -------------
59  //  -- eax : argument count (preserved for callee)
60  //  -- edx : new target (preserved for callee)
61  //  -- edi : target function (preserved for callee)
62  // -----------------------------------
63  {
64    FrameScope scope(masm, StackFrame::INTERNAL);
65    // Push the number of arguments to the callee.
66    __ SmiTag(eax);
67    __ push(eax);
68    // Push a copy of the target function and the new target.
69    __ push(edi);
70    __ push(edx);
71    // Function is also the parameter to the runtime call.
72    __ push(edi);
73
74    __ CallRuntime(function_id, 1);
75    __ mov(ebx, eax);
76
77    // Restore target function and new target.
78    __ pop(edx);
79    __ pop(edi);
80    __ pop(eax);
81    __ SmiUntag(eax);
82  }
83
84  __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize));
85  __ jmp(ebx);
86}
87
88static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
89  __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
90  __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kCodeOffset));
91  __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize));
92  __ jmp(ebx);
93}
94
95void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
96  // Checking whether the queued function is ready for install is optional,
97  // since we come across interrupts and stack checks elsewhere.  However,
98  // not checking may delay installing ready functions, and always checking
99  // would be quite expensive.  A good compromise is to first check against
100  // stack limit as a cue for an interrupt signal.
101  Label ok;
102  ExternalReference stack_limit =
103      ExternalReference::address_of_stack_limit(masm->isolate());
104  __ cmp(esp, Operand::StaticVariable(stack_limit));
105  __ j(above_equal, &ok, Label::kNear);
106
107  GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
108
109  __ bind(&ok);
110  GenerateTailCallToSharedCode(masm);
111}
112
113namespace {
114
115void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
116                                    bool create_implicit_receiver,
117                                    bool check_derived_construct) {
118  // ----------- S t a t e -------------
119  //  -- eax: number of arguments
120  //  -- esi: context
121  //  -- edi: constructor function
122  //  -- edx: new target
123  // -----------------------------------
124
125  // Enter a construct frame.
126  {
127    FrameScope scope(masm, StackFrame::CONSTRUCT);
128
129    // Preserve the incoming parameters on the stack.
130    __ SmiTag(eax);
131    __ push(esi);
132    __ push(eax);
133
134    if (create_implicit_receiver) {
135      // Allocate the new receiver object.
136      __ Push(edi);
137      __ Push(edx);
138      FastNewObjectStub stub(masm->isolate());
139      __ CallStub(&stub);
140      __ mov(ebx, eax);
141      __ Pop(edx);
142      __ Pop(edi);
143
144      // ----------- S t a t e -------------
145      //  -- edi: constructor function
146      //  -- ebx: newly allocated object
147      //  -- edx: new target
148      // -----------------------------------
149
150      // Retrieve smi-tagged arguments count from the stack.
151      __ mov(eax, Operand(esp, 0));
152    }
153
154    __ SmiUntag(eax);
155
156    if (create_implicit_receiver) {
157      // Push the allocated receiver to the stack. We need two copies
158      // because we may have to return the original one and the calling
159      // conventions dictate that the called function pops the receiver.
160      __ push(ebx);
161      __ push(ebx);
162    } else {
163      __ PushRoot(Heap::kTheHoleValueRootIndex);
164    }
165
166    // Set up pointer to last argument.
167    __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));
168
169    // Copy arguments and receiver to the expression stack.
170    Label loop, entry;
171    __ mov(ecx, eax);
172    __ jmp(&entry);
173    __ bind(&loop);
174    __ push(Operand(ebx, ecx, times_4, 0));
175    __ bind(&entry);
176    __ dec(ecx);
177    __ j(greater_equal, &loop);
178
179    // Call the function.
180    ParameterCount actual(eax);
181    __ InvokeFunction(edi, edx, actual, CALL_FUNCTION,
182                      CheckDebugStepCallWrapper());
183
184    // Store offset of return address for deoptimizer.
185    if (create_implicit_receiver && !is_api_function) {
186      masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
187    }
188
189    // Restore context from the frame.
190    __ mov(esi, Operand(ebp, ConstructFrameConstants::kContextOffset));
191
192    if (create_implicit_receiver) {
193      // If the result is an object (in the ECMA sense), we should get rid
194      // of the receiver and use the result.
195      Label use_receiver, exit;
196
197      // If the result is a smi, it is *not* an object in the ECMA sense.
198      __ JumpIfSmi(eax, &use_receiver, Label::kNear);
199
200      // If the type of the result (stored in its map) is less than
201      // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
202      __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
203      __ j(above_equal, &exit, Label::kNear);
204
205      // Throw away the result of the constructor invocation and use the
206      // on-stack receiver as the result.
207      __ bind(&use_receiver);
208      __ mov(eax, Operand(esp, 0));
209
210      // Restore the arguments count and leave the construct frame. The
211      // arguments count is stored below the receiver.
212      __ bind(&exit);
213      __ mov(ebx, Operand(esp, 1 * kPointerSize));
214    } else {
215      __ mov(ebx, Operand(esp, 0));
216    }
217
218    // Leave construct frame.
219  }
220
221  // ES6 9.2.2. Step 13+
222  // Check that the result is not a Smi, indicating that the constructor result
223  // from a derived class is neither undefined nor an Object.
224  if (check_derived_construct) {
225    Label dont_throw;
226    __ JumpIfNotSmi(eax, &dont_throw);
227    {
228      FrameScope scope(masm, StackFrame::INTERNAL);
229      __ CallRuntime(Runtime::kThrowDerivedConstructorReturnedNonObject);
230    }
231    __ bind(&dont_throw);
232  }
233
234  // Remove caller arguments from the stack and return.
235  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
236  __ pop(ecx);
237  __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver
238  __ push(ecx);
239  if (create_implicit_receiver) {
240    __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
241  }
242  __ ret(0);
243}
244
245}  // namespace
246
247void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
248  Generate_JSConstructStubHelper(masm, false, true, false);
249}
250
251void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
252  Generate_JSConstructStubHelper(masm, true, false, false);
253}
254
255void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
256  Generate_JSConstructStubHelper(masm, false, false, false);
257}
258
259void Builtins::Generate_JSBuiltinsConstructStubForDerived(
260    MacroAssembler* masm) {
261  Generate_JSConstructStubHelper(masm, false, false, true);
262}
263
264void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
265  FrameScope scope(masm, StackFrame::INTERNAL);
266  __ push(edi);
267  __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
268}
269
270enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt };
271
272// Clobbers ecx, edx, edi; preserves all other registers.
273static void Generate_CheckStackOverflow(MacroAssembler* masm,
274                                        IsTagged eax_is_tagged) {
275  // eax   : the number of items to be pushed to the stack
276  //
277  // Check the stack for overflow. We are not trying to catch
278  // interruptions (e.g. debug break and preemption) here, so the "real stack
279  // limit" is checked.
280  Label okay;
281  ExternalReference real_stack_limit =
282      ExternalReference::address_of_real_stack_limit(masm->isolate());
283  __ mov(edi, Operand::StaticVariable(real_stack_limit));
284  // Make ecx the space we have left. The stack might already be overflowed
285  // here which will cause ecx to become negative.
286  __ mov(ecx, esp);
287  __ sub(ecx, edi);
288  // Make edx the space we need for the array when it is unrolled onto the
289  // stack.
290  __ mov(edx, eax);
291  int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0;
292  __ shl(edx, kPointerSizeLog2 - smi_tag);
293  // Check if the arguments will overflow the stack.
294  __ cmp(ecx, edx);
295  __ j(greater, &okay);  // Signed comparison.
296
297  // Out of stack space.
298  __ CallRuntime(Runtime::kThrowStackOverflow);
299
300  __ bind(&okay);
301}
302
303static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
304                                             bool is_construct) {
305  ProfileEntryHookStub::MaybeCallEntryHook(masm);
306
307  {
308    FrameScope scope(masm, StackFrame::INTERNAL);
309
310    // Setup the context (we need to use the caller context from the isolate).
311    ExternalReference context_address(Isolate::kContextAddress,
312                                      masm->isolate());
313    __ mov(esi, Operand::StaticVariable(context_address));
314
315    // Load the previous frame pointer (ebx) to access C arguments
316    __ mov(ebx, Operand(ebp, 0));
317
318    // Push the function and the receiver onto the stack.
319    __ push(Operand(ebx, EntryFrameConstants::kFunctionArgOffset));
320    __ push(Operand(ebx, EntryFrameConstants::kReceiverArgOffset));
321
322    // Load the number of arguments and setup pointer to the arguments.
323    __ mov(eax, Operand(ebx, EntryFrameConstants::kArgcOffset));
324    __ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset));
325
326    // Check if we have enough stack space to push all arguments.
327    // Expects argument count in eax. Clobbers ecx, edx, edi.
328    Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt);
329
330    // Copy arguments to the stack in a loop.
331    Label loop, entry;
332    __ Move(ecx, Immediate(0));
333    __ jmp(&entry, Label::kNear);
334    __ bind(&loop);
335    __ mov(edx, Operand(ebx, ecx, times_4, 0));  // push parameter from argv
336    __ push(Operand(edx, 0));                    // dereference handle
337    __ inc(ecx);
338    __ bind(&entry);
339    __ cmp(ecx, eax);
340    __ j(not_equal, &loop);
341
342    // Load the previous frame pointer (ebx) to access C arguments
343    __ mov(ebx, Operand(ebp, 0));
344
345    // Get the new.target and function from the frame.
346    __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset));
347    __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset));
348
349    // Invoke the code.
350    Handle<Code> builtin = is_construct
351                               ? masm->isolate()->builtins()->Construct()
352                               : masm->isolate()->builtins()->Call();
353    __ Call(builtin, RelocInfo::CODE_TARGET);
354
355    // Exit the internal frame. Notice that this also removes the empty.
356    // context and the function left on the stack by the code
357    // invocation.
358  }
359  __ ret(kPointerSize);  // Remove receiver.
360}
361
362void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
363  Generate_JSEntryTrampolineHelper(masm, false);
364}
365
366void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
367  Generate_JSEntryTrampolineHelper(masm, true);
368}
369
370// static
371void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
372  // ----------- S t a t e -------------
373  //  -- eax    : the value to pass to the generator
374  //  -- ebx    : the JSGeneratorObject to resume
375  //  -- edx    : the resume mode (tagged)
376  //  -- esp[0] : return address
377  // -----------------------------------
378  __ AssertGeneratorObject(ebx);
379
380  // Store input value into generator object.
381  __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
382  __ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
383                      kDontSaveFPRegs);
384
385  // Store resume mode into generator object.
386  __ mov(FieldOperand(ebx, JSGeneratorObject::kResumeModeOffset), edx);
387
388  // Load suspended function and context.
389  __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
390  __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
391
392  // Flood function if we are stepping.
393  Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
394  Label stepping_prepared;
395  ExternalReference last_step_action =
396      ExternalReference::debug_last_step_action_address(masm->isolate());
397  STATIC_ASSERT(StepFrame > StepIn);
398  __ cmpb(Operand::StaticVariable(last_step_action), Immediate(StepIn));
399  __ j(greater_equal, &prepare_step_in_if_stepping);
400
401  // Flood function if we need to continue stepping in the suspended generator.
402  ExternalReference debug_suspended_generator =
403      ExternalReference::debug_suspended_generator_address(masm->isolate());
404  __ cmp(ebx, Operand::StaticVariable(debug_suspended_generator));
405  __ j(equal, &prepare_step_in_suspended_generator);
406  __ bind(&stepping_prepared);
407
408  // Pop return address.
409  __ PopReturnAddressTo(eax);
410
411  // Push receiver.
412  __ Push(FieldOperand(ebx, JSGeneratorObject::kReceiverOffset));
413
414  // ----------- S t a t e -------------
415  //  -- eax    : return address
416  //  -- ebx    : the JSGeneratorObject to resume
417  //  -- edx    : the resume mode (tagged)
418  //  -- edi    : generator function
419  //  -- esi    : generator context
420  //  -- esp[0] : generator receiver
421  // -----------------------------------
422
423  // Push holes for arguments to generator function. Since the parser forced
424  // context allocation for any variables in generators, the actual argument
425  // values have already been copied into the context and these dummy values
426  // will never be used.
427  __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
428  __ mov(ecx,
429         FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
430  {
431    Label done_loop, loop;
432    __ bind(&loop);
433    __ sub(ecx, Immediate(Smi::FromInt(1)));
434    __ j(carry, &done_loop, Label::kNear);
435    __ PushRoot(Heap::kTheHoleValueRootIndex);
436    __ jmp(&loop);
437    __ bind(&done_loop);
438  }
439
440  // Dispatch on the kind of generator object.
441  Label old_generator;
442  __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
443  __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset));
444  __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx);
445  __ j(not_equal, &old_generator);
446
447  // New-style (ignition/turbofan) generator object
448  {
449    __ PushReturnAddressFrom(eax);
450    __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
451    __ mov(eax,
452           FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
453    // We abuse new.target both to indicate that this is a resume call and to
454    // pass in the generator object.  In ordinary calls, new.target is always
455    // undefined because generator functions are non-constructable.
456    __ mov(edx, ebx);
457    __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset));
458  }
459
460  // Old-style (full-codegen) generator object
461  __ bind(&old_generator);
462  {
463    // Enter a new JavaScript frame, and initialize its slots as they were when
464    // the generator was suspended.
465    FrameScope scope(masm, StackFrame::MANUAL);
466    __ PushReturnAddressFrom(eax);  // Return address.
467    __ Push(ebp);                   // Caller's frame pointer.
468    __ Move(ebp, esp);
469    __ Push(esi);  // Callee's context.
470    __ Push(edi);  // Callee's JS Function.
471
472    // Restore the operand stack.
473    __ mov(eax, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset));
474    {
475      Label done_loop, loop;
476      __ Move(ecx, Smi::kZero);
477      __ bind(&loop);
478      __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset));
479      __ j(equal, &done_loop, Label::kNear);
480      __ Push(FieldOperand(eax, ecx, times_half_pointer_size,
481                           FixedArray::kHeaderSize));
482      __ add(ecx, Immediate(Smi::FromInt(1)));
483      __ jmp(&loop);
484      __ bind(&done_loop);
485    }
486
487    // Reset operand stack so we don't leak.
488    __ mov(FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset),
489           Immediate(masm->isolate()->factory()->empty_fixed_array()));
490
491    // Resume the generator function at the continuation.
492    __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
493    __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
494    __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset));
495    __ SmiUntag(ecx);
496    __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize));
497    __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset),
498           Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
499    __ mov(eax, ebx);  // Continuation expects generator object in eax.
500    __ jmp(edx);
501  }
502
503  __ bind(&prepare_step_in_if_stepping);
504  {
505    FrameScope scope(masm, StackFrame::INTERNAL);
506    __ Push(ebx);
507    __ Push(edx);
508    __ Push(edi);
509    __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
510    __ Pop(edx);
511    __ Pop(ebx);
512    __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
513  }
514  __ jmp(&stepping_prepared);
515
516  __ bind(&prepare_step_in_suspended_generator);
517  {
518    FrameScope scope(masm, StackFrame::INTERNAL);
519    __ Push(ebx);
520    __ Push(edx);
521    __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
522    __ Pop(edx);
523    __ Pop(ebx);
524    __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
525  }
526  __ jmp(&stepping_prepared);
527}
528
529static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
530                                  Register scratch2) {
531  Register args_count = scratch1;
532  Register return_pc = scratch2;
533
534  // Get the arguments + reciever count.
535  __ mov(args_count,
536         Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
537  __ mov(args_count,
538         FieldOperand(args_count, BytecodeArray::kParameterSizeOffset));
539
540  // Leave the frame (also dropping the register file).
541  __ leave();
542
543  // Drop receiver + arguments.
544  __ pop(return_pc);
545  __ add(esp, args_count);
546  __ push(return_pc);
547}
548
549// Generate code for entering a JS function with the interpreter.
550// On entry to the function the receiver and arguments have been pushed on the
551// stack left to right.  The actual argument count matches the formal parameter
552// count expected by the function.
553//
554// The live registers are:
555//   o edi: the JS function object being called
556//   o edx: the new target
557//   o esi: our context
558//   o ebp: the caller's frame pointer
559//   o esp: stack pointer (pointing to return address)
560//
561// The function builds an interpreter frame.  See InterpreterFrameConstants in
562// frames.h for its layout.
563void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
564  ProfileEntryHookStub::MaybeCallEntryHook(masm);
565
566  // Open a frame scope to indicate that there is a frame on the stack.  The
567  // MANUAL indicates that the scope shouldn't actually generate code to set up
568  // the frame (that is done below).
569  FrameScope frame_scope(masm, StackFrame::MANUAL);
570  __ push(ebp);  // Caller's frame pointer.
571  __ mov(ebp, esp);
572  __ push(esi);  // Callee's context.
573  __ push(edi);  // Callee's JS function.
574  __ push(edx);  // Callee's new target.
575
576  // Get the bytecode array from the function object (or from the DebugInfo if
577  // it is present) and load it into kInterpreterBytecodeArrayRegister.
578  __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
579  Label load_debug_bytecode_array, bytecode_array_loaded;
580  __ cmp(FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset),
581         Immediate(DebugInfo::uninitialized()));
582  __ j(not_equal, &load_debug_bytecode_array);
583  __ mov(kInterpreterBytecodeArrayRegister,
584         FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset));
585  __ bind(&bytecode_array_loaded);
586
587  // Check whether we should continue to use the interpreter.
588  Label switch_to_different_code_kind;
589  __ Move(ecx, masm->CodeObject());  // Self-reference to this code.
590  __ cmp(ecx, FieldOperand(eax, SharedFunctionInfo::kCodeOffset));
591  __ j(not_equal, &switch_to_different_code_kind);
592
593  // Increment invocation count for the function.
594  __ EmitLoadTypeFeedbackVector(ecx);
595  __ add(FieldOperand(ecx,
596                      TypeFeedbackVector::kInvocationCountIndex * kPointerSize +
597                          TypeFeedbackVector::kHeaderSize),
598         Immediate(Smi::FromInt(1)));
599
600  // Check function data field is actually a BytecodeArray object.
601  if (FLAG_debug_code) {
602    __ AssertNotSmi(kInterpreterBytecodeArrayRegister);
603    __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE,
604                     eax);
605    __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
606  }
607
608  // Push bytecode array.
609  __ push(kInterpreterBytecodeArrayRegister);
610  // Push Smi tagged initial bytecode array offset.
611  __ push(Immediate(Smi::FromInt(BytecodeArray::kHeaderSize - kHeapObjectTag)));
612
613  // Allocate the local and temporary register file on the stack.
614  {
615    // Load frame size from the BytecodeArray object.
616    __ mov(ebx, FieldOperand(kInterpreterBytecodeArrayRegister,
617                             BytecodeArray::kFrameSizeOffset));
618
619    // Do a stack check to ensure we don't go over the limit.
620    Label ok;
621    __ mov(ecx, esp);
622    __ sub(ecx, ebx);
623    ExternalReference stack_limit =
624        ExternalReference::address_of_real_stack_limit(masm->isolate());
625    __ cmp(ecx, Operand::StaticVariable(stack_limit));
626    __ j(above_equal, &ok);
627    __ CallRuntime(Runtime::kThrowStackOverflow);
628    __ bind(&ok);
629
630    // If ok, push undefined as the initial value for all register file entries.
631    Label loop_header;
632    Label loop_check;
633    __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value()));
634    __ jmp(&loop_check);
635    __ bind(&loop_header);
636    // TODO(rmcilroy): Consider doing more than one push per loop iteration.
637    __ push(eax);
638    // Continue loop if not done.
639    __ bind(&loop_check);
640    __ sub(ebx, Immediate(kPointerSize));
641    __ j(greater_equal, &loop_header);
642  }
643
644  // Load accumulator, bytecode offset and dispatch table into registers.
645  __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
646  __ mov(kInterpreterBytecodeOffsetRegister,
647         Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
648  __ mov(kInterpreterDispatchTableRegister,
649         Immediate(ExternalReference::interpreter_dispatch_table_address(
650             masm->isolate())));
651
652  // Dispatch to the first bytecode handler for the function.
653  __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
654                          kInterpreterBytecodeOffsetRegister, times_1, 0));
655  __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
656                      times_pointer_size, 0));
657  __ call(ebx);
658  masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
659
660  // The return value is in eax.
661  LeaveInterpreterFrame(masm, ebx, ecx);
662  __ ret(0);
663
664  // Load debug copy of the bytecode array.
665  __ bind(&load_debug_bytecode_array);
666  Register debug_info = kInterpreterBytecodeArrayRegister;
667  __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset));
668  __ mov(kInterpreterBytecodeArrayRegister,
669         FieldOperand(debug_info, DebugInfo::kDebugBytecodeArrayIndex));
670  __ jmp(&bytecode_array_loaded);
671
672  // If the shared code is no longer this entry trampoline, then the underlying
673  // function has been switched to a different kind of code and we heal the
674  // closure by switching the code entry field over to the new code as well.
675  __ bind(&switch_to_different_code_kind);
676  __ pop(edx);  // Callee's new target.
677  __ pop(edi);  // Callee's JS function.
678  __ pop(esi);  // Callee's context.
679  __ leave();   // Leave the frame so we can tail call.
680  __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
681  __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset));
682  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
683  __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx);
684  __ RecordWriteCodeEntryField(edi, ecx, ebx);
685  __ jmp(ecx);
686}
687
688static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
689                                        Register scratch1, Register scratch2,
690                                        Label* stack_overflow,
691                                        bool include_receiver = false) {
692  // Check the stack for overflow. We are not trying to catch
693  // interruptions (e.g. debug break and preemption) here, so the "real stack
694  // limit" is checked.
695  ExternalReference real_stack_limit =
696      ExternalReference::address_of_real_stack_limit(masm->isolate());
697  __ mov(scratch1, Operand::StaticVariable(real_stack_limit));
698  // Make scratch2 the space we have left. The stack might already be overflowed
699  // here which will cause scratch2 to become negative.
700  __ mov(scratch2, esp);
701  __ sub(scratch2, scratch1);
702  // Make scratch1 the space we need for the array when it is unrolled onto the
703  // stack.
704  __ mov(scratch1, num_args);
705  if (include_receiver) {
706    __ add(scratch1, Immediate(1));
707  }
708  __ shl(scratch1, kPointerSizeLog2);
709  // Check if the arguments will overflow the stack.
710  __ cmp(scratch2, scratch1);
711  __ j(less_equal, stack_overflow);  // Signed comparison.
712}
713
714static void Generate_InterpreterPushArgs(MacroAssembler* masm,
715                                         Register array_limit,
716                                         Register start_address) {
717  // ----------- S t a t e -------------
718  //  -- start_address : Pointer to the last argument in the args array.
719  //  -- array_limit : Pointer to one before the first argument in the
720  //                   args array.
721  // -----------------------------------
722  Label loop_header, loop_check;
723  __ jmp(&loop_check);
724  __ bind(&loop_header);
725  __ Push(Operand(start_address, 0));
726  __ sub(start_address, Immediate(kPointerSize));
727  __ bind(&loop_check);
728  __ cmp(start_address, array_limit);
729  __ j(greater, &loop_header, Label::kNear);
730}
731
732// static
733void Builtins::Generate_InterpreterPushArgsAndCallImpl(
734    MacroAssembler* masm, TailCallMode tail_call_mode,
735    CallableType function_type) {
736  // ----------- S t a t e -------------
737  //  -- eax : the number of arguments (not including the receiver)
738  //  -- ebx : the address of the first argument to be pushed. Subsequent
739  //           arguments should be consecutive above this, in the same order as
740  //           they are to be pushed onto the stack.
741  //  -- edi : the target to call (can be any Object).
742  // -----------------------------------
743  Label stack_overflow;
744  // Compute the expected number of arguments.
745  __ mov(ecx, eax);
746  __ add(ecx, Immediate(1));  // Add one for receiver.
747
748  // Add a stack check before pushing the arguments. We need an extra register
749  // to perform a stack check. So push it onto the stack temporarily. This
750  // might cause stack overflow, but it will be detected by the check.
751  __ Push(edi);
752  Generate_StackOverflowCheck(masm, ecx, edx, edi, &stack_overflow);
753  __ Pop(edi);
754
755  // Pop return address to allow tail-call after pushing arguments.
756  __ Pop(edx);
757
758  // Find the address of the last argument.
759  __ shl(ecx, kPointerSizeLog2);
760  __ neg(ecx);
761  __ add(ecx, ebx);
762  Generate_InterpreterPushArgs(masm, ecx, ebx);
763
764  // Call the target.
765  __ Push(edx);  // Re-push return address.
766
767  if (function_type == CallableType::kJSFunction) {
768    __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
769                                                      tail_call_mode),
770            RelocInfo::CODE_TARGET);
771  } else {
772    DCHECK_EQ(function_type, CallableType::kAny);
773    __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
774                                              tail_call_mode),
775            RelocInfo::CODE_TARGET);
776  }
777
778  __ bind(&stack_overflow);
779  {
780    // Pop the temporary registers, so that return address is on top of stack.
781    __ Pop(edi);
782
783    __ TailCallRuntime(Runtime::kThrowStackOverflow);
784
785    // This should be unreachable.
786    __ int3();
787  }
788}
789
790namespace {
791
792// This function modified start_addr, and only reads the contents of num_args
793// register. scratch1 and scratch2 are used as temporary registers. Their
794// original values are restored after the use.
795void Generate_InterpreterPushArgsAndReturnAddress(
796    MacroAssembler* masm, Register num_args, Register start_addr,
797    Register scratch1, Register scratch2, bool receiver_in_args,
798    int num_slots_above_ret_addr, Label* stack_overflow) {
799  // We have to move return address and the temporary registers above it
800  // before we can copy arguments onto the stack. To achieve this:
801  // Step 1: Increment the stack pointer by num_args + 1 (for receiver).
802  // Step 2: Move the return address and values above it to the top of stack.
803  // Step 3: Copy the arguments into the correct locations.
804  //  current stack    =====>    required stack layout
805  // |             |            | scratch1      | (2) <-- esp(1)
806  // |             |            | ....          | (2)
807  // |             |            | scratch-n     | (2)
808  // |             |            | return addr   | (2)
809  // |             |            | arg N         | (3)
810  // | scratch1    | <-- esp    | ....          |
811  // | ....        |            | arg 0         |
812  // | scratch-n   |            | arg 0         |
813  // | return addr |            | receiver slot |
814
815  // Check for stack overflow before we increment the stack pointer.
816  Generate_StackOverflowCheck(masm, num_args, scratch1, scratch2,
817                              stack_overflow, true);
818
819// Step 1 - Update the stack pointer. scratch1 already contains the required
820// increment to the stack. i.e. num_args + 1 stack slots. This is computed in
821// the Generate_StackOverflowCheck.
822
823#ifdef _MSC_VER
824  // TODO(mythria): Move it to macro assembler.
825  // In windows, we cannot increment the stack size by more than one page
826  // (mimimum page size is 4KB) without accessing at least one byte on the
827  // page. Check this:
828  // https://msdn.microsoft.com/en-us/library/aa227153(v=vs.60).aspx.
829  const int page_size = 4 * 1024;
830  Label check_offset, update_stack_pointer;
831  __ bind(&check_offset);
832  __ cmp(scratch1, page_size);
833  __ j(less, &update_stack_pointer);
834  __ sub(esp, Immediate(page_size));
835  // Just to touch the page, before we increment further.
836  __ mov(Operand(esp, 0), Immediate(0));
837  __ sub(scratch1, Immediate(page_size));
838  __ jmp(&check_offset);
839  __ bind(&update_stack_pointer);
840#endif
841
842  __ sub(esp, scratch1);
843
844  // Step 2 move return_address and slots above it to the correct locations.
845  // Move from top to bottom, otherwise we may overwrite when num_args = 0 or 1,
846  // basically when the source and destination overlap. We at least need one
847  // extra slot for receiver, so no extra checks are required to avoid copy.
848  for (int i = 0; i < num_slots_above_ret_addr + 1; i++) {
849    __ mov(scratch1,
850           Operand(esp, num_args, times_pointer_size, (i + 1) * kPointerSize));
851    __ mov(Operand(esp, i * kPointerSize), scratch1);
852  }
853
854  // Step 3 copy arguments to correct locations.
855  if (receiver_in_args) {
856    __ mov(scratch1, num_args);
857    __ add(scratch1, Immediate(1));
858  } else {
859    // Slot meant for receiver contains return address. Reset it so that
860    // we will not incorrectly interpret return address as an object.
861    __ mov(Operand(esp, num_args, times_pointer_size,
862                   (num_slots_above_ret_addr + 1) * kPointerSize),
863           Immediate(0));
864    __ mov(scratch1, num_args);
865  }
866
867  Label loop_header, loop_check;
868  __ jmp(&loop_check);
869  __ bind(&loop_header);
870  __ mov(scratch2, Operand(start_addr, 0));
871  __ mov(Operand(esp, scratch1, times_pointer_size,
872                 num_slots_above_ret_addr * kPointerSize),
873         scratch2);
874  __ sub(start_addr, Immediate(kPointerSize));
875  __ sub(scratch1, Immediate(1));
876  __ bind(&loop_check);
877  __ cmp(scratch1, Immediate(0));
878  __ j(greater, &loop_header, Label::kNear);
879}
880
881}  // end anonymous namespace
882
883// static
884void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
885    MacroAssembler* masm, CallableType construct_type) {
886  // ----------- S t a t e -------------
887  //  -- eax : the number of arguments (not including the receiver)
888  //  -- edx : the new target
889  //  -- edi : the constructor
890  //  -- ebx : allocation site feedback (if available or undefined)
891  //  -- ecx : the address of the first argument to be pushed. Subsequent
892  //           arguments should be consecutive above this, in the same order as
893  //           they are to be pushed onto the stack.
894  // -----------------------------------
895  Label stack_overflow;
896  // We need two scratch registers. Push edi and edx onto stack.
897  __ Push(edi);
898  __ Push(edx);
899
900  // Push arguments and move return address to the top of stack.
901  // The eax register is readonly. The ecx register will be modified. The edx
902  // and edi registers will be modified but restored to their original values.
903  Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false,
904                                               2, &stack_overflow);
905
906  // Restore edi and edx
907  __ Pop(edx);
908  __ Pop(edi);
909
910  __ AssertUndefinedOrAllocationSite(ebx);
911  if (construct_type == CallableType::kJSFunction) {
912    // Tail call to the function-specific construct stub (still in the caller
913    // context at this point).
914    __ AssertFunction(edi);
915
916    __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
917    __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
918    __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
919    __ jmp(ecx);
920  } else {
921    DCHECK_EQ(construct_type, CallableType::kAny);
922
923    // Call the constructor with unmodified eax, edi, edx values.
924    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
925  }
926
927  __ bind(&stack_overflow);
928  {
929    // Pop the temporary registers, so that return address is on top of stack.
930    __ Pop(edx);
931    __ Pop(edi);
932
933    __ TailCallRuntime(Runtime::kThrowStackOverflow);
934
935    // This should be unreachable.
936    __ int3();
937  }
938}
939
940// static
941void Builtins::Generate_InterpreterPushArgsAndConstructArray(
942    MacroAssembler* masm) {
943  // ----------- S t a t e -------------
944  //  -- eax : the number of arguments (not including the receiver)
945  //  -- edx : the target to call checked to be Array function.
946  //  -- ebx : the allocation site feedback
947  //  -- ecx : the address of the first argument to be pushed. Subsequent
948  //           arguments should be consecutive above this, in the same order as
949  //           they are to be pushed onto the stack.
950  // -----------------------------------
951  Label stack_overflow;
952  // We need two scratch registers. Register edi is available, push edx onto
953  // stack.
954  __ Push(edx);
955
956  // Push arguments and move return address to the top of stack.
957  // The eax register is readonly. The ecx register will be modified. The edx
958  // and edi registers will be modified but restored to their original values.
959  Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, true,
960                                               1, &stack_overflow);
961
962  // Restore edx.
963  __ Pop(edx);
964
965  // Array constructor expects constructor in edi. It is same as edx here.
966  __ Move(edi, edx);
967
968  ArrayConstructorStub stub(masm->isolate());
969  __ TailCallStub(&stub);
970
971  __ bind(&stack_overflow);
972  {
973    // Pop the temporary registers, so that return address is on top of stack.
974    __ Pop(edx);
975
976    __ TailCallRuntime(Runtime::kThrowStackOverflow);
977
978    // This should be unreachable.
979    __ int3();
980  }
981}
982
983static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
984  // Set the return address to the correct point in the interpreter entry
985  // trampoline.
986  Smi* interpreter_entry_return_pc_offset(
987      masm->isolate()->heap()->interpreter_entry_return_pc_offset());
988  DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
989  __ LoadHeapObject(ebx,
990                    masm->isolate()->builtins()->InterpreterEntryTrampoline());
991  __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() +
992                        Code::kHeaderSize - kHeapObjectTag));
993  __ push(ebx);
994
995  // Initialize the dispatch table register.
996  __ mov(kInterpreterDispatchTableRegister,
997         Immediate(ExternalReference::interpreter_dispatch_table_address(
998             masm->isolate())));
999
1000  // Get the bytecode array pointer from the frame.
1001  __ mov(kInterpreterBytecodeArrayRegister,
1002         Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1003
1004  if (FLAG_debug_code) {
1005    // Check function data field is actually a BytecodeArray object.
1006    __ AssertNotSmi(kInterpreterBytecodeArrayRegister);
1007    __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE,
1008                     ebx);
1009    __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1010  }
1011
1012  // Get the target bytecode offset from the frame.
1013  __ mov(kInterpreterBytecodeOffsetRegister,
1014         Operand(ebp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1015  __ SmiUntag(kInterpreterBytecodeOffsetRegister);
1016
1017  // Dispatch to the target bytecode.
1018  __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister,
1019                          kInterpreterBytecodeOffsetRegister, times_1, 0));
1020  __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx,
1021                      times_pointer_size, 0));
1022  __ jmp(ebx);
1023}
1024
1025void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
1026  // Advance the current bytecode offset stored within the given interpreter
1027  // stack frame. This simulates what all bytecode handlers do upon completion
1028  // of the underlying operation.
1029  __ mov(ebx, Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1030  __ mov(edx, Operand(ebp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1031  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1032  {
1033    FrameScope scope(masm, StackFrame::INTERNAL);
1034    __ Push(kInterpreterAccumulatorRegister);
1035    __ Push(ebx);  // First argument is the bytecode array.
1036    __ Push(edx);  // Second argument is the bytecode offset.
1037    __ CallRuntime(Runtime::kInterpreterAdvanceBytecodeOffset);
1038    __ Move(edx, eax);  // Result is the new bytecode offset.
1039    __ Pop(kInterpreterAccumulatorRegister);
1040  }
1041  __ mov(Operand(ebp, InterpreterFrameConstants::kBytecodeOffsetFromFp), edx);
1042
1043  Generate_InterpreterEnterBytecode(masm);
1044}
1045
1046void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1047  Generate_InterpreterEnterBytecode(masm);
1048}
1049
1050void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
1051  // ----------- S t a t e -------------
1052  //  -- eax : argument count (preserved for callee)
1053  //  -- edx : new target (preserved for callee)
1054  //  -- edi : target function (preserved for callee)
1055  // -----------------------------------
1056  // First lookup code, maybe we don't need to compile!
1057  Label gotta_call_runtime, gotta_call_runtime_no_stack;
1058  Label try_shared;
1059  Label loop_top, loop_bottom;
1060
1061  Register closure = edi;
1062  Register new_target = edx;
1063  Register argument_count = eax;
1064
1065  __ push(argument_count);
1066  __ push(new_target);
1067  __ push(closure);
1068
1069  Register map = argument_count;
1070  Register index = ebx;
1071  __ mov(map, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1072  __ mov(map, FieldOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
1073  __ mov(index, FieldOperand(map, FixedArray::kLengthOffset));
1074  __ cmp(index, Immediate(Smi::FromInt(2)));
1075  __ j(less, &gotta_call_runtime);
1076
1077  // Find literals.
1078  // edx : native context
1079  // ebx : length / index
1080  // eax : optimized code map
1081  // stack[0] : new target
1082  // stack[4] : closure
1083  Register native_context = edx;
1084  __ mov(native_context, NativeContextOperand());
1085
1086  __ bind(&loop_top);
1087  Register temp = edi;
1088
1089  // Does the native context match?
1090  __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
1091                            SharedFunctionInfo::kOffsetToPreviousContext));
1092  __ mov(temp, FieldOperand(temp, WeakCell::kValueOffset));
1093  __ cmp(temp, native_context);
1094  __ j(not_equal, &loop_bottom);
1095  // OSR id set to none?
1096  __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
1097                            SharedFunctionInfo::kOffsetToPreviousOsrAstId));
1098  const int bailout_id = BailoutId::None().ToInt();
1099  __ cmp(temp, Immediate(Smi::FromInt(bailout_id)));
1100  __ j(not_equal, &loop_bottom);
1101  // Literals available?
1102  __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
1103                            SharedFunctionInfo::kOffsetToPreviousLiterals));
1104  __ mov(temp, FieldOperand(temp, WeakCell::kValueOffset));
1105  __ JumpIfSmi(temp, &gotta_call_runtime);
1106
1107  // Save the literals in the closure.
1108  __ mov(ecx, Operand(esp, 0));
1109  __ mov(FieldOperand(ecx, JSFunction::kLiteralsOffset), temp);
1110  __ push(index);
1111  __ RecordWriteField(ecx, JSFunction::kLiteralsOffset, temp, index,
1112                      kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
1113  __ pop(index);
1114
1115  // Code available?
1116  Register entry = ecx;
1117  __ mov(entry, FieldOperand(map, index, times_half_pointer_size,
1118                             SharedFunctionInfo::kOffsetToPreviousCachedCode));
1119  __ mov(entry, FieldOperand(entry, WeakCell::kValueOffset));
1120  __ JumpIfSmi(entry, &try_shared);
1121
1122  // Found literals and code. Get them into the closure and return.
1123  __ pop(closure);
1124  // Store code entry in the closure.
1125  __ lea(entry, FieldOperand(entry, Code::kHeaderSize));
1126  __ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
1127  __ RecordWriteCodeEntryField(closure, entry, eax);
1128
1129  // Link the closure into the optimized function list.
1130  // ecx : code entry
1131  // edx : native context
1132  // edi : closure
1133  __ mov(ebx,
1134         ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1135  __ mov(FieldOperand(closure, JSFunction::kNextFunctionLinkOffset), ebx);
1136  __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, ebx, eax,
1137                      kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
1138  const int function_list_offset =
1139      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
1140  __ mov(ContextOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST),
1141         closure);
1142  // Save closure before the write barrier.
1143  __ mov(ebx, closure);
1144  __ RecordWriteContextSlot(native_context, function_list_offset, closure, eax,
1145                            kDontSaveFPRegs);
1146  __ mov(closure, ebx);
1147  __ pop(new_target);
1148  __ pop(argument_count);
1149  __ jmp(entry);
1150
1151  __ bind(&loop_bottom);
1152  __ sub(index, Immediate(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
1153  __ cmp(index, Immediate(Smi::FromInt(1)));
1154  __ j(greater, &loop_top);
1155
1156  // We found neither literals nor code.
1157  __ jmp(&gotta_call_runtime);
1158
1159  __ bind(&try_shared);
1160  __ pop(closure);
1161  __ pop(new_target);
1162  __ pop(argument_count);
1163  __ mov(entry, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1164  // Is the shared function marked for tier up?
1165  __ test_b(FieldOperand(entry, SharedFunctionInfo::kMarkedForTierUpByteOffset),
1166            Immediate(1 << SharedFunctionInfo::kMarkedForTierUpBitWithinByte));
1167  __ j(not_zero, &gotta_call_runtime_no_stack);
1168  // Is the full code valid?
1169  __ mov(entry, FieldOperand(entry, SharedFunctionInfo::kCodeOffset));
1170  __ mov(ebx, FieldOperand(entry, Code::kFlagsOffset));
1171  __ and_(ebx, Code::KindField::kMask);
1172  __ shr(ebx, Code::KindField::kShift);
1173  __ cmp(ebx, Immediate(Code::BUILTIN));
1174  __ j(equal, &gotta_call_runtime_no_stack);
1175  // Yes, install the full code.
1176  __ lea(entry, FieldOperand(entry, Code::kHeaderSize));
1177  __ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
1178  __ RecordWriteCodeEntryField(closure, entry, ebx);
1179  __ jmp(entry);
1180
1181  __ bind(&gotta_call_runtime);
1182  __ pop(closure);
1183  __ pop(new_target);
1184  __ pop(argument_count);
1185  __ bind(&gotta_call_runtime_no_stack);
1186
1187  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1188}
1189
1190void Builtins::Generate_CompileBaseline(MacroAssembler* masm) {
1191  GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline);
1192}
1193
1194void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
1195  GenerateTailCallToReturnedCode(masm,
1196                                 Runtime::kCompileOptimized_NotConcurrent);
1197}
1198
1199void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
1200  GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
1201}
1202
1203void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
1204  // ----------- S t a t e -------------
1205  //  -- eax : argument count (preserved for callee)
1206  //  -- edx : new target (preserved for callee)
1207  //  -- edi : target function (preserved for callee)
1208  // -----------------------------------
1209  Label failed;
1210  {
1211    FrameScope scope(masm, StackFrame::INTERNAL);
1212    // Preserve argument count for later compare.
1213    __ mov(ecx, eax);
1214    // Push the number of arguments to the callee.
1215    __ SmiTag(eax);
1216    __ push(eax);
1217    // Push a copy of the target function and the new target.
1218    __ push(edi);
1219    __ push(edx);
1220
1221    // The function.
1222    __ push(edi);
1223    // Copy arguments from caller (stdlib, foreign, heap).
1224    Label args_done;
1225    for (int j = 0; j < 4; ++j) {
1226      Label over;
1227      if (j < 3) {
1228        __ cmp(ecx, Immediate(j));
1229        __ j(not_equal, &over, Label::kNear);
1230      }
1231      for (int i = j - 1; i >= 0; --i) {
1232        __ Push(Operand(
1233            ebp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
1234      }
1235      for (int i = 0; i < 3 - j; ++i) {
1236        __ PushRoot(Heap::kUndefinedValueRootIndex);
1237      }
1238      if (j < 3) {
1239        __ jmp(&args_done, Label::kNear);
1240        __ bind(&over);
1241      }
1242    }
1243    __ bind(&args_done);
1244
1245    // Call runtime, on success unwind frame, and parent frame.
1246    __ CallRuntime(Runtime::kInstantiateAsmJs, 4);
1247    // A smi 0 is returned on failure, an object on success.
1248    __ JumpIfSmi(eax, &failed, Label::kNear);
1249
1250    __ Drop(2);
1251    __ Pop(ecx);
1252    __ SmiUntag(ecx);
1253    scope.GenerateLeaveFrame();
1254
1255    __ PopReturnAddressTo(ebx);
1256    __ inc(ecx);
1257    __ lea(esp, Operand(esp, ecx, times_pointer_size, 0));
1258    __ PushReturnAddressFrom(ebx);
1259    __ ret(0);
1260
1261    __ bind(&failed);
1262    // Restore target function and new target.
1263    __ pop(edx);
1264    __ pop(edi);
1265    __ pop(eax);
1266    __ SmiUntag(eax);
1267  }
1268  // On failure, tail call back to regular js.
1269  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1270}
1271
1272static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
1273  // For now, we are relying on the fact that make_code_young doesn't do any
1274  // garbage collection which allows us to save/restore the registers without
1275  // worrying about which of them contain pointers. We also don't build an
1276  // internal frame to make the code faster, since we shouldn't have to do stack
1277  // crawls in MakeCodeYoung. This seems a bit fragile.
1278
1279  // Re-execute the code that was patched back to the young age when
1280  // the stub returns.
1281  __ sub(Operand(esp, 0), Immediate(5));
1282  __ pushad();
1283  __ mov(eax, Operand(esp, 8 * kPointerSize));
1284  {
1285    FrameScope scope(masm, StackFrame::MANUAL);
1286    __ PrepareCallCFunction(2, ebx);
1287    __ mov(Operand(esp, 1 * kPointerSize),
1288           Immediate(ExternalReference::isolate_address(masm->isolate())));
1289    __ mov(Operand(esp, 0), eax);
1290    __ CallCFunction(
1291        ExternalReference::get_make_code_young_function(masm->isolate()), 2);
1292  }
1293  __ popad();
1294  __ ret(0);
1295}
1296
1297#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                  \
1298  void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \
1299      MacroAssembler* masm) {                                 \
1300    GenerateMakeCodeYoungAgainCommon(masm);                   \
1301  }                                                           \
1302  void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(  \
1303      MacroAssembler* masm) {                                 \
1304    GenerateMakeCodeYoungAgainCommon(masm);                   \
1305  }
1306CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
1307#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
1308
1309void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
1310  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
1311  // that make_code_young doesn't do any garbage collection which allows us to
1312  // save/restore the registers without worrying about which of them contain
1313  // pointers.
1314  __ pushad();
1315  __ mov(eax, Operand(esp, 8 * kPointerSize));
1316  __ sub(eax, Immediate(Assembler::kCallInstructionLength));
1317  {  // NOLINT
1318    FrameScope scope(masm, StackFrame::MANUAL);
1319    __ PrepareCallCFunction(2, ebx);
1320    __ mov(Operand(esp, 1 * kPointerSize),
1321           Immediate(ExternalReference::isolate_address(masm->isolate())));
1322    __ mov(Operand(esp, 0), eax);
1323    __ CallCFunction(
1324        ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
1325        2);
1326  }
1327  __ popad();
1328
1329  // Perform prologue operations usually performed by the young code stub.
1330  __ pop(eax);   // Pop return address into scratch register.
1331  __ push(ebp);  // Caller's frame pointer.
1332  __ mov(ebp, esp);
1333  __ push(esi);  // Callee's context.
1334  __ push(edi);  // Callee's JS Function.
1335  __ push(eax);  // Push return address after frame prologue.
1336
1337  // Jump to point after the code-age stub.
1338  __ ret(0);
1339}
1340
1341void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
1342  GenerateMakeCodeYoungAgainCommon(masm);
1343}
1344
1345void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
1346  Generate_MarkCodeAsExecutedOnce(masm);
1347}
1348
1349static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
1350                                             SaveFPRegsMode save_doubles) {
1351  // Enter an internal frame.
1352  {
1353    FrameScope scope(masm, StackFrame::INTERNAL);
1354
1355    // Preserve registers across notification, this is important for compiled
1356    // stubs that tail call the runtime on deopts passing their parameters in
1357    // registers.
1358    __ pushad();
1359    __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles);
1360    __ popad();
1361    // Tear down internal frame.
1362  }
1363
1364  __ pop(MemOperand(esp, 0));  // Ignore state offset
1365  __ ret(0);  // Return to IC Miss stub, continuation still on stack.
1366}
1367
1368void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
1369  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
1370}
1371
1372void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
1373  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
1374}
1375
1376static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
1377                                             Deoptimizer::BailoutType type) {
1378  {
1379    FrameScope scope(masm, StackFrame::INTERNAL);
1380
1381    // Pass deoptimization type to the runtime system.
1382    __ push(Immediate(Smi::FromInt(static_cast<int>(type))));
1383    __ CallRuntime(Runtime::kNotifyDeoptimized);
1384
1385    // Tear down internal frame.
1386  }
1387
1388  // Get the full codegen state from the stack and untag it.
1389  __ mov(ecx, Operand(esp, 1 * kPointerSize));
1390  __ SmiUntag(ecx);
1391
1392  // Switch on the state.
1393  Label not_no_registers, not_tos_eax;
1394  __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS));
1395  __ j(not_equal, &not_no_registers, Label::kNear);
1396  __ ret(1 * kPointerSize);  // Remove state.
1397
1398  __ bind(&not_no_registers);
1399  DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code());
1400  __ mov(eax, Operand(esp, 2 * kPointerSize));
1401  __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER));
1402  __ j(not_equal, &not_tos_eax, Label::kNear);
1403  __ ret(2 * kPointerSize);  // Remove state, eax.
1404
1405  __ bind(&not_tos_eax);
1406  __ Abort(kNoCasesLeft);
1407}
1408
1409void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1410  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1411}
1412
1413void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
1414  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1415}
1416
1417void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
1418  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1419}
1420
1421// static
1422void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1423  // ----------- S t a t e -------------
1424  //  -- eax     : argc
1425  //  -- esp[0]  : return address
1426  //  -- esp[4]  : argArray
1427  //  -- esp[8]  : thisArg
1428  //  -- esp[12] : receiver
1429  // -----------------------------------
1430
1431  // 1. Load receiver into edi, argArray into eax (if present), remove all
1432  // arguments from the stack (including the receiver), and push thisArg (if
1433  // present) instead.
1434  {
1435    Label no_arg_array, no_this_arg;
1436    __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1437    __ mov(ebx, edx);
1438    __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1439    __ test(eax, eax);
1440    __ j(zero, &no_this_arg, Label::kNear);
1441    {
1442      __ mov(edx, Operand(esp, eax, times_pointer_size, 0));
1443      __ cmp(eax, Immediate(1));
1444      __ j(equal, &no_arg_array, Label::kNear);
1445      __ mov(ebx, Operand(esp, eax, times_pointer_size, -kPointerSize));
1446      __ bind(&no_arg_array);
1447    }
1448    __ bind(&no_this_arg);
1449    __ PopReturnAddressTo(ecx);
1450    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1451    __ Push(edx);
1452    __ PushReturnAddressFrom(ecx);
1453    __ Move(eax, ebx);
1454  }
1455
1456  // ----------- S t a t e -------------
1457  //  -- eax    : argArray
1458  //  -- edi    : receiver
1459  //  -- esp[0] : return address
1460  //  -- esp[4] : thisArg
1461  // -----------------------------------
1462
1463  // 2. Make sure the receiver is actually callable.
1464  Label receiver_not_callable;
1465  __ JumpIfSmi(edi, &receiver_not_callable, Label::kNear);
1466  __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1467  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1468            Immediate(1 << Map::kIsCallable));
1469  __ j(zero, &receiver_not_callable, Label::kNear);
1470
1471  // 3. Tail call with no arguments if argArray is null or undefined.
1472  Label no_arguments;
1473  __ JumpIfRoot(eax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear);
1474  __ JumpIfRoot(eax, Heap::kUndefinedValueRootIndex, &no_arguments,
1475                Label::kNear);
1476
1477  // 4a. Apply the receiver to the given argArray (passing undefined for
1478  // new.target).
1479  __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1480  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1481
1482  // 4b. The argArray is either null or undefined, so we tail call without any
1483  // arguments to the receiver.
1484  __ bind(&no_arguments);
1485  {
1486    __ Set(eax, 0);
1487    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1488  }
1489
1490  // 4c. The receiver is not callable, throw an appropriate TypeError.
1491  __ bind(&receiver_not_callable);
1492  {
1493    __ mov(Operand(esp, kPointerSize), edi);
1494    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1495  }
1496}
1497
1498// static
1499void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
1500  // Stack Layout:
1501  // esp[0]           : Return address
1502  // esp[8]           : Argument n
1503  // esp[16]          : Argument n-1
1504  //  ...
1505  // esp[8 * n]       : Argument 1
1506  // esp[8 * (n + 1)] : Receiver (callable to call)
1507  //
1508  // eax contains the number of arguments, n, not counting the receiver.
1509  //
1510  // 1. Make sure we have at least one argument.
1511  {
1512    Label done;
1513    __ test(eax, eax);
1514    __ j(not_zero, &done, Label::kNear);
1515    __ PopReturnAddressTo(ebx);
1516    __ PushRoot(Heap::kUndefinedValueRootIndex);
1517    __ PushReturnAddressFrom(ebx);
1518    __ inc(eax);
1519    __ bind(&done);
1520  }
1521
1522  // 2. Get the callable to call (passed as receiver) from the stack.
1523  __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1524
1525  // 3. Shift arguments and return address one slot down on the stack
1526  //    (overwriting the original receiver).  Adjust argument count to make
1527  //    the original first argument the new receiver.
1528  {
1529    Label loop;
1530    __ mov(ecx, eax);
1531    __ bind(&loop);
1532    __ mov(ebx, Operand(esp, ecx, times_pointer_size, 0));
1533    __ mov(Operand(esp, ecx, times_pointer_size, kPointerSize), ebx);
1534    __ dec(ecx);
1535    __ j(not_sign, &loop);  // While non-negative (to copy return address).
1536    __ pop(ebx);            // Discard copy of return address.
1537    __ dec(eax);  // One fewer argument (first argument is new receiver).
1538  }
1539
1540  // 4. Call the callable.
1541  __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1542}
1543
1544void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1545  // ----------- S t a t e -------------
1546  //  -- eax     : argc
1547  //  -- esp[0]  : return address
1548  //  -- esp[4]  : argumentsList
1549  //  -- esp[8]  : thisArgument
1550  //  -- esp[12] : target
1551  //  -- esp[16] : receiver
1552  // -----------------------------------
1553
1554  // 1. Load target into edi (if present), argumentsList into eax (if present),
1555  // remove all arguments from the stack (including the receiver), and push
1556  // thisArgument (if present) instead.
1557  {
1558    Label done;
1559    __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
1560    __ mov(edx, edi);
1561    __ mov(ebx, edi);
1562    __ cmp(eax, Immediate(1));
1563    __ j(below, &done, Label::kNear);
1564    __ mov(edi, Operand(esp, eax, times_pointer_size, -0 * kPointerSize));
1565    __ j(equal, &done, Label::kNear);
1566    __ mov(edx, Operand(esp, eax, times_pointer_size, -1 * kPointerSize));
1567    __ cmp(eax, Immediate(3));
1568    __ j(below, &done, Label::kNear);
1569    __ mov(ebx, Operand(esp, eax, times_pointer_size, -2 * kPointerSize));
1570    __ bind(&done);
1571    __ PopReturnAddressTo(ecx);
1572    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1573    __ Push(edx);
1574    __ PushReturnAddressFrom(ecx);
1575    __ Move(eax, ebx);
1576  }
1577
1578  // ----------- S t a t e -------------
1579  //  -- eax    : argumentsList
1580  //  -- edi    : target
1581  //  -- esp[0] : return address
1582  //  -- esp[4] : thisArgument
1583  // -----------------------------------
1584
1585  // 2. Make sure the target is actually callable.
1586  Label target_not_callable;
1587  __ JumpIfSmi(edi, &target_not_callable, Label::kNear);
1588  __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1589  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1590            Immediate(1 << Map::kIsCallable));
1591  __ j(zero, &target_not_callable, Label::kNear);
1592
1593  // 3a. Apply the target to the given argumentsList (passing undefined for
1594  // new.target).
1595  __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1596  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1597
1598  // 3b. The target is not callable, throw an appropriate TypeError.
1599  __ bind(&target_not_callable);
1600  {
1601    __ mov(Operand(esp, kPointerSize), edi);
1602    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1603  }
1604}
1605
1606void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1607  // ----------- S t a t e -------------
1608  //  -- eax     : argc
1609  //  -- esp[0]  : return address
1610  //  -- esp[4]  : new.target (optional)
1611  //  -- esp[8]  : argumentsList
1612  //  -- esp[12] : target
1613  //  -- esp[16] : receiver
1614  // -----------------------------------
1615
1616  // 1. Load target into edi (if present), argumentsList into eax (if present),
1617  // new.target into edx (if present, otherwise use target), remove all
1618  // arguments from the stack (including the receiver), and push thisArgument
1619  // (if present) instead.
1620  {
1621    Label done;
1622    __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
1623    __ mov(edx, edi);
1624    __ mov(ebx, edi);
1625    __ cmp(eax, Immediate(1));
1626    __ j(below, &done, Label::kNear);
1627    __ mov(edi, Operand(esp, eax, times_pointer_size, -0 * kPointerSize));
1628    __ mov(edx, edi);
1629    __ j(equal, &done, Label::kNear);
1630    __ mov(ebx, Operand(esp, eax, times_pointer_size, -1 * kPointerSize));
1631    __ cmp(eax, Immediate(3));
1632    __ j(below, &done, Label::kNear);
1633    __ mov(edx, Operand(esp, eax, times_pointer_size, -2 * kPointerSize));
1634    __ bind(&done);
1635    __ PopReturnAddressTo(ecx);
1636    __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1637    __ PushRoot(Heap::kUndefinedValueRootIndex);
1638    __ PushReturnAddressFrom(ecx);
1639    __ Move(eax, ebx);
1640  }
1641
1642  // ----------- S t a t e -------------
1643  //  -- eax    : argumentsList
1644  //  -- edx    : new.target
1645  //  -- edi    : target
1646  //  -- esp[0] : return address
1647  //  -- esp[4] : receiver (undefined)
1648  // -----------------------------------
1649
1650  // 2. Make sure the target is actually a constructor.
1651  Label target_not_constructor;
1652  __ JumpIfSmi(edi, &target_not_constructor, Label::kNear);
1653  __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1654  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1655            Immediate(1 << Map::kIsConstructor));
1656  __ j(zero, &target_not_constructor, Label::kNear);
1657
1658  // 3. Make sure the target is actually a constructor.
1659  Label new_target_not_constructor;
1660  __ JumpIfSmi(edx, &new_target_not_constructor, Label::kNear);
1661  __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
1662  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1663            Immediate(1 << Map::kIsConstructor));
1664  __ j(zero, &new_target_not_constructor, Label::kNear);
1665
1666  // 4a. Construct the target with the given new.target and argumentsList.
1667  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1668
1669  // 4b. The target is not a constructor, throw an appropriate TypeError.
1670  __ bind(&target_not_constructor);
1671  {
1672    __ mov(Operand(esp, kPointerSize), edi);
1673    __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
1674  }
1675
1676  // 4c. The new.target is not a constructor, throw an appropriate TypeError.
1677  __ bind(&new_target_not_constructor);
1678  {
1679    __ mov(Operand(esp, kPointerSize), edx);
1680    __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
1681  }
1682}
1683
1684void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
1685  // ----------- S t a t e -------------
1686  //  -- eax : argc
1687  //  -- esp[0] : return address
1688  //  -- esp[4] : last argument
1689  // -----------------------------------
1690  Label generic_array_code;
1691
1692  // Get the InternalArray function.
1693  __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi);
1694
1695  if (FLAG_debug_code) {
1696    // Initial map for the builtin InternalArray function should be a map.
1697    __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1698    // Will both indicate a NULL and a Smi.
1699    __ test(ebx, Immediate(kSmiTagMask));
1700    __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction);
1701    __ CmpObjectType(ebx, MAP_TYPE, ecx);
1702    __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction);
1703  }
1704
1705  // Run the native code for the InternalArray function called as a normal
1706  // function.
1707  // tail call a stub
1708  InternalArrayConstructorStub stub(masm->isolate());
1709  __ TailCallStub(&stub);
1710}
1711
1712void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
1713  // ----------- S t a t e -------------
1714  //  -- eax : argc
1715  //  -- esp[0] : return address
1716  //  -- esp[4] : last argument
1717  // -----------------------------------
1718  Label generic_array_code;
1719
1720  // Get the Array function.
1721  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi);
1722  __ mov(edx, edi);
1723
1724  if (FLAG_debug_code) {
1725    // Initial map for the builtin Array function should be a map.
1726    __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1727    // Will both indicate a NULL and a Smi.
1728    __ test(ebx, Immediate(kSmiTagMask));
1729    __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction);
1730    __ CmpObjectType(ebx, MAP_TYPE, ecx);
1731    __ Assert(equal, kUnexpectedInitialMapForArrayFunction);
1732  }
1733
1734  // Run the native code for the Array function called as a normal function.
1735  // tail call a stub
1736  __ mov(ebx, masm->isolate()->factory()->undefined_value());
1737  ArrayConstructorStub stub(masm->isolate());
1738  __ TailCallStub(&stub);
1739}
1740
1741// static
1742void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
1743  // ----------- S t a t e -------------
1744  //  -- eax                 : number of arguments
1745  //  -- edi                 : function
1746  //  -- esi                 : context
1747  //  -- esp[0]              : return address
1748  //  -- esp[(argc - n) * 8] : arg[n] (zero-based)
1749  //  -- esp[(argc + 1) * 8] : receiver
1750  // -----------------------------------
1751  Condition const cc = (kind == MathMaxMinKind::kMin) ? below : above;
1752  Heap::RootListIndex const root_index =
1753      (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex
1754                                     : Heap::kMinusInfinityValueRootIndex;
1755  XMMRegister const reg = (kind == MathMaxMinKind::kMin) ? xmm1 : xmm0;
1756
1757  // Load the accumulator with the default return value (either -Infinity or
1758  // +Infinity), with the tagged value in edx and the double value in xmm0.
1759  __ LoadRoot(edx, root_index);
1760  __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
1761  __ Move(ecx, eax);
1762
1763  Label done_loop, loop;
1764  __ bind(&loop);
1765  {
1766    // Check if all parameters done.
1767    __ test(ecx, ecx);
1768    __ j(zero, &done_loop);
1769
1770    // Load the next parameter tagged value into ebx.
1771    __ mov(ebx, Operand(esp, ecx, times_pointer_size, 0));
1772
1773    // Load the double value of the parameter into xmm1, maybe converting the
1774    // parameter to a number first using the ToNumber builtin if necessary.
1775    Label convert, convert_smi, convert_number, done_convert;
1776    __ bind(&convert);
1777    __ JumpIfSmi(ebx, &convert_smi);
1778    __ JumpIfRoot(FieldOperand(ebx, HeapObject::kMapOffset),
1779                  Heap::kHeapNumberMapRootIndex, &convert_number);
1780    {
1781      // Parameter is not a Number, use the ToNumber builtin to convert it.
1782      FrameScope scope(masm, StackFrame::MANUAL);
1783      __ SmiTag(eax);
1784      __ SmiTag(ecx);
1785      __ EnterBuiltinFrame(esi, edi, eax);
1786      __ Push(ecx);
1787      __ Push(edx);
1788      __ mov(eax, ebx);
1789      __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1790      __ mov(ebx, eax);
1791      __ Pop(edx);
1792      __ Pop(ecx);
1793      __ LeaveBuiltinFrame(esi, edi, eax);
1794      __ SmiUntag(ecx);
1795      __ SmiUntag(eax);
1796      {
1797        // Restore the double accumulator value (xmm0).
1798        Label restore_smi, done_restore;
1799        __ JumpIfSmi(edx, &restore_smi, Label::kNear);
1800        __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
1801        __ jmp(&done_restore, Label::kNear);
1802        __ bind(&restore_smi);
1803        __ SmiUntag(edx);
1804        __ Cvtsi2sd(xmm0, edx);
1805        __ SmiTag(edx);
1806        __ bind(&done_restore);
1807      }
1808    }
1809    __ jmp(&convert);
1810    __ bind(&convert_number);
1811    __ movsd(xmm1, FieldOperand(ebx, HeapNumber::kValueOffset));
1812    __ jmp(&done_convert, Label::kNear);
1813    __ bind(&convert_smi);
1814    __ SmiUntag(ebx);
1815    __ Cvtsi2sd(xmm1, ebx);
1816    __ SmiTag(ebx);
1817    __ bind(&done_convert);
1818
1819    // Perform the actual comparison with the accumulator value on the left hand
1820    // side (xmm0) and the next parameter value on the right hand side (xmm1).
1821    Label compare_equal, compare_nan, compare_swap, done_compare;
1822    __ ucomisd(xmm0, xmm1);
1823    __ j(parity_even, &compare_nan, Label::kNear);
1824    __ j(cc, &done_compare, Label::kNear);
1825    __ j(equal, &compare_equal, Label::kNear);
1826
1827    // Result is on the right hand side.
1828    __ bind(&compare_swap);
1829    __ movaps(xmm0, xmm1);
1830    __ mov(edx, ebx);
1831    __ jmp(&done_compare, Label::kNear);
1832
1833    // At least one side is NaN, which means that the result will be NaN too.
1834    __ bind(&compare_nan);
1835    __ LoadRoot(edx, Heap::kNanValueRootIndex);
1836    __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
1837    __ jmp(&done_compare, Label::kNear);
1838
1839    // Left and right hand side are equal, check for -0 vs. +0.
1840    __ bind(&compare_equal);
1841    __ Push(edi);  // Preserve function in edi.
1842    __ movmskpd(edi, reg);
1843    __ test(edi, Immediate(1));
1844    __ Pop(edi);
1845    __ j(not_zero, &compare_swap);
1846
1847    __ bind(&done_compare);
1848    __ dec(ecx);
1849    __ jmp(&loop);
1850  }
1851
1852  __ bind(&done_loop);
1853  __ PopReturnAddressTo(ecx);
1854  __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1855  __ PushReturnAddressFrom(ecx);
1856  __ mov(eax, edx);
1857  __ Ret();
1858}
1859
1860// static
1861void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
1862  // ----------- S t a t e -------------
1863  //  -- eax                 : number of arguments
1864  //  -- edi                 : constructor function
1865  //  -- esi                 : context
1866  //  -- esp[0]              : return address
1867  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1868  //  -- esp[(argc + 1) * 4] : receiver
1869  // -----------------------------------
1870
1871  // 1. Load the first argument into ebx.
1872  Label no_arguments;
1873  {
1874    __ test(eax, eax);
1875    __ j(zero, &no_arguments, Label::kNear);
1876    __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1877  }
1878
1879  // 2a. Convert the first argument to a number.
1880  {
1881    FrameScope scope(masm, StackFrame::MANUAL);
1882    __ SmiTag(eax);
1883    __ EnterBuiltinFrame(esi, edi, eax);
1884    __ mov(eax, ebx);
1885    __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1886    __ LeaveBuiltinFrame(esi, edi, ebx);  // Argc popped to ebx.
1887    __ SmiUntag(ebx);
1888  }
1889
1890  {
1891    // Drop all arguments including the receiver.
1892    __ PopReturnAddressTo(ecx);
1893    __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
1894    __ PushReturnAddressFrom(ecx);
1895    __ Ret();
1896  }
1897
1898  // 2b. No arguments, return +0 (already in eax).
1899  __ bind(&no_arguments);
1900  __ ret(1 * kPointerSize);
1901}
1902
1903// static
1904void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
1905  // ----------- S t a t e -------------
1906  //  -- eax                 : number of arguments
1907  //  -- edi                 : constructor function
1908  //  -- edx                 : new target
1909  //  -- esi                 : context
1910  //  -- esp[0]              : return address
1911  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1912  //  -- esp[(argc + 1) * 4] : receiver
1913  // -----------------------------------
1914
1915  // 1. Make sure we operate in the context of the called function.
1916  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1917
1918  // Store argc in r8.
1919  __ mov(ecx, eax);
1920  __ SmiTag(ecx);
1921
1922  // 2. Load the first argument into ebx.
1923  {
1924    Label no_arguments, done;
1925    __ test(eax, eax);
1926    __ j(zero, &no_arguments, Label::kNear);
1927    __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1928    __ jmp(&done, Label::kNear);
1929    __ bind(&no_arguments);
1930    __ Move(ebx, Smi::kZero);
1931    __ bind(&done);
1932  }
1933
1934  // 3. Make sure ebx is a number.
1935  {
1936    Label done_convert;
1937    __ JumpIfSmi(ebx, &done_convert);
1938    __ CompareRoot(FieldOperand(ebx, HeapObject::kMapOffset),
1939                   Heap::kHeapNumberMapRootIndex);
1940    __ j(equal, &done_convert);
1941    {
1942      FrameScope scope(masm, StackFrame::MANUAL);
1943      __ EnterBuiltinFrame(esi, edi, ecx);
1944      __ Push(edx);
1945      __ Move(eax, ebx);
1946      __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1947      __ Move(ebx, eax);
1948      __ Pop(edx);
1949      __ LeaveBuiltinFrame(esi, edi, ecx);
1950    }
1951    __ bind(&done_convert);
1952  }
1953
1954  // 4. Check if new target and constructor differ.
1955  Label drop_frame_and_ret, done_alloc, new_object;
1956  __ cmp(edx, edi);
1957  __ j(not_equal, &new_object);
1958
1959  // 5. Allocate a JSValue wrapper for the number.
1960  __ AllocateJSValue(eax, edi, ebx, esi, &done_alloc);
1961  __ jmp(&drop_frame_and_ret);
1962
1963  __ bind(&done_alloc);
1964  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));  // Restore esi.
1965
1966  // 6. Fallback to the runtime to create new object.
1967  __ bind(&new_object);
1968  {
1969    FrameScope scope(masm, StackFrame::MANUAL);
1970    __ EnterBuiltinFrame(esi, edi, ecx);
1971    __ Push(ebx);  // the first argument
1972    FastNewObjectStub stub(masm->isolate());
1973    __ CallStub(&stub);
1974    __ Pop(FieldOperand(eax, JSValue::kValueOffset));
1975    __ LeaveBuiltinFrame(esi, edi, ecx);
1976  }
1977
1978  __ bind(&drop_frame_and_ret);
1979  {
1980    // Drop all arguments including the receiver.
1981    __ PopReturnAddressTo(esi);
1982    __ SmiUntag(ecx);
1983    __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize));
1984    __ PushReturnAddressFrom(esi);
1985    __ Ret();
1986  }
1987}
1988
1989// static
1990void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
1991  // ----------- S t a t e -------------
1992  //  -- eax                 : number of arguments
1993  //  -- edi                 : constructor function
1994  //  -- esi                 : context
1995  //  -- esp[0]              : return address
1996  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
1997  //  -- esp[(argc + 1) * 4] : receiver
1998  // -----------------------------------
1999
2000  // 1. Load the first argument into eax.
2001  Label no_arguments;
2002  {
2003    __ mov(ebx, eax);  // Store argc in ebx.
2004    __ test(eax, eax);
2005    __ j(zero, &no_arguments, Label::kNear);
2006    __ mov(eax, Operand(esp, eax, times_pointer_size, 0));
2007  }
2008
2009  // 2a. At least one argument, return eax if it's a string, otherwise
2010  // dispatch to appropriate conversion.
2011  Label drop_frame_and_ret, to_string, symbol_descriptive_string;
2012  {
2013    __ JumpIfSmi(eax, &to_string, Label::kNear);
2014    STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
2015    __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
2016    __ j(above, &to_string, Label::kNear);
2017    __ j(equal, &symbol_descriptive_string, Label::kNear);
2018    __ jmp(&drop_frame_and_ret, Label::kNear);
2019  }
2020
2021  // 2b. No arguments, return the empty string (and pop the receiver).
2022  __ bind(&no_arguments);
2023  {
2024    __ LoadRoot(eax, Heap::kempty_stringRootIndex);
2025    __ ret(1 * kPointerSize);
2026  }
2027
2028  // 3a. Convert eax to a string.
2029  __ bind(&to_string);
2030  {
2031    FrameScope scope(masm, StackFrame::MANUAL);
2032    __ SmiTag(ebx);
2033    __ EnterBuiltinFrame(esi, edi, ebx);
2034    __ Call(masm->isolate()->builtins()->ToString(), RelocInfo::CODE_TARGET);
2035    __ LeaveBuiltinFrame(esi, edi, ebx);
2036    __ SmiUntag(ebx);
2037  }
2038  __ jmp(&drop_frame_and_ret, Label::kNear);
2039
2040  // 3b. Convert symbol in eax to a string.
2041  __ bind(&symbol_descriptive_string);
2042  {
2043    __ PopReturnAddressTo(ecx);
2044    __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
2045    __ Push(eax);
2046    __ PushReturnAddressFrom(ecx);
2047    __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
2048  }
2049
2050  __ bind(&drop_frame_and_ret);
2051  {
2052    // Drop all arguments including the receiver.
2053    __ PopReturnAddressTo(ecx);
2054    __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
2055    __ PushReturnAddressFrom(ecx);
2056    __ Ret();
2057  }
2058}
2059
2060// static
2061void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
2062  // ----------- S t a t e -------------
2063  //  -- eax                 : number of arguments
2064  //  -- edi                 : constructor function
2065  //  -- edx                 : new target
2066  //  -- esi                 : context
2067  //  -- esp[0]              : return address
2068  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
2069  //  -- esp[(argc + 1) * 4] : receiver
2070  // -----------------------------------
2071
2072  // 1. Make sure we operate in the context of the called function.
2073  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2074
2075  __ mov(ebx, eax);
2076
2077  // 2. Load the first argument into eax.
2078  {
2079    Label no_arguments, done;
2080    __ test(ebx, ebx);
2081    __ j(zero, &no_arguments, Label::kNear);
2082    __ mov(eax, Operand(esp, ebx, times_pointer_size, 0));
2083    __ jmp(&done, Label::kNear);
2084    __ bind(&no_arguments);
2085    __ LoadRoot(eax, Heap::kempty_stringRootIndex);
2086    __ bind(&done);
2087  }
2088
2089  // 3. Make sure eax is a string.
2090  {
2091    Label convert, done_convert;
2092    __ JumpIfSmi(eax, &convert, Label::kNear);
2093    __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
2094    __ j(below, &done_convert);
2095    __ bind(&convert);
2096    {
2097      FrameScope scope(masm, StackFrame::MANUAL);
2098      __ SmiTag(ebx);
2099      __ EnterBuiltinFrame(esi, edi, ebx);
2100      __ Push(edx);
2101      __ Call(masm->isolate()->builtins()->ToString(), RelocInfo::CODE_TARGET);
2102      __ Pop(edx);
2103      __ LeaveBuiltinFrame(esi, edi, ebx);
2104      __ SmiUntag(ebx);
2105    }
2106    __ bind(&done_convert);
2107  }
2108
2109  // 4. Check if new target and constructor differ.
2110  Label drop_frame_and_ret, done_alloc, new_object;
2111  __ cmp(edx, edi);
2112  __ j(not_equal, &new_object);
2113
2114  // 5. Allocate a JSValue wrapper for the string.
2115  // AllocateJSValue can't handle src == dst register. Reuse esi and restore it
2116  // as needed after the call.
2117  __ mov(esi, eax);
2118  __ AllocateJSValue(eax, edi, esi, ecx, &done_alloc);
2119  __ jmp(&drop_frame_and_ret);
2120
2121  __ bind(&done_alloc);
2122  {
2123    // Restore eax to the first argument and esi to the context.
2124    __ mov(eax, esi);
2125    __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2126  }
2127
2128  // 6. Fallback to the runtime to create new object.
2129  __ bind(&new_object);
2130  {
2131    FrameScope scope(masm, StackFrame::MANUAL);
2132    __ SmiTag(ebx);
2133    __ EnterBuiltinFrame(esi, edi, ebx);
2134    __ Push(eax);  // the first argument
2135    FastNewObjectStub stub(masm->isolate());
2136    __ CallStub(&stub);
2137    __ Pop(FieldOperand(eax, JSValue::kValueOffset));
2138    __ LeaveBuiltinFrame(esi, edi, ebx);
2139    __ SmiUntag(ebx);
2140  }
2141
2142  __ bind(&drop_frame_and_ret);
2143  {
2144    // Drop all arguments including the receiver.
2145    __ PopReturnAddressTo(ecx);
2146    __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
2147    __ PushReturnAddressFrom(ecx);
2148    __ Ret();
2149  }
2150}
2151
2152static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2153  __ push(ebp);
2154  __ mov(ebp, esp);
2155
2156  // Store the arguments adaptor context sentinel.
2157  __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2158
2159  // Push the function on the stack.
2160  __ push(edi);
2161
2162  // Preserve the number of arguments on the stack. Must preserve eax,
2163  // ebx and ecx because these registers are used when copying the
2164  // arguments and the receiver.
2165  STATIC_ASSERT(kSmiTagSize == 1);
2166  __ lea(edi, Operand(eax, eax, times_1, kSmiTag));
2167  __ push(edi);
2168}
2169
2170static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
2171  // Retrieve the number of arguments from the stack.
2172  __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
2173
2174  // Leave the frame.
2175  __ leave();
2176
2177  // Remove caller arguments from the stack.
2178  STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
2179  __ pop(ecx);
2180  __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver
2181  __ push(ecx);
2182}
2183
2184// static
2185void Builtins::Generate_Apply(MacroAssembler* masm) {
2186  // ----------- S t a t e -------------
2187  //  -- eax    : argumentsList
2188  //  -- edi    : target
2189  //  -- edx    : new.target (checked to be constructor or undefined)
2190  //  -- esp[0] : return address.
2191  //  -- esp[4] : thisArgument
2192  // -----------------------------------
2193
2194  // Create the list of arguments from the array-like argumentsList.
2195  {
2196    Label create_arguments, create_array, create_runtime, done_create;
2197    __ JumpIfSmi(eax, &create_runtime);
2198
2199    // Load the map of argumentsList into ecx.
2200    __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
2201
2202    // Load native context into ebx.
2203    __ mov(ebx, NativeContextOperand());
2204
2205    // Check if argumentsList is an (unmodified) arguments object.
2206    __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
2207    __ j(equal, &create_arguments);
2208    __ cmp(ecx, ContextOperand(ebx, Context::STRICT_ARGUMENTS_MAP_INDEX));
2209    __ j(equal, &create_arguments);
2210
2211    // Check if argumentsList is a fast JSArray.
2212    __ CmpInstanceType(ecx, JS_ARRAY_TYPE);
2213    __ j(equal, &create_array);
2214
2215    // Ask the runtime to create the list (actually a FixedArray).
2216    __ bind(&create_runtime);
2217    {
2218      FrameScope scope(masm, StackFrame::INTERNAL);
2219      __ Push(edi);
2220      __ Push(edx);
2221      __ Push(eax);
2222      __ CallRuntime(Runtime::kCreateListFromArrayLike);
2223      __ Pop(edx);
2224      __ Pop(edi);
2225      __ mov(ebx, FieldOperand(eax, FixedArray::kLengthOffset));
2226      __ SmiUntag(ebx);
2227    }
2228    __ jmp(&done_create);
2229
2230    // Try to create the list from an arguments object.
2231    __ bind(&create_arguments);
2232    __ mov(ebx, FieldOperand(eax, JSArgumentsObject::kLengthOffset));
2233    __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset));
2234    __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
2235    __ j(not_equal, &create_runtime);
2236    __ SmiUntag(ebx);
2237    __ mov(eax, ecx);
2238    __ jmp(&done_create);
2239
2240    // Try to create the list from a JSArray object.
2241    __ bind(&create_array);
2242    __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
2243    __ DecodeField<Map::ElementsKindBits>(ecx);
2244    STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2245    STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2246    STATIC_ASSERT(FAST_ELEMENTS == 2);
2247    __ cmp(ecx, Immediate(FAST_ELEMENTS));
2248    __ j(above, &create_runtime);
2249    __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
2250    __ j(equal, &create_runtime);
2251    __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
2252    __ SmiUntag(ebx);
2253    __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
2254
2255    __ bind(&done_create);
2256  }
2257
2258  // Check for stack overflow.
2259  {
2260    // Check the stack for overflow. We are not trying to catch interruptions
2261    // (i.e. debug break and preemption) here, so check the "real stack limit".
2262    Label done;
2263    ExternalReference real_stack_limit =
2264        ExternalReference::address_of_real_stack_limit(masm->isolate());
2265    __ mov(ecx, Operand::StaticVariable(real_stack_limit));
2266    // Make ecx the space we have left. The stack might already be overflowed
2267    // here which will cause ecx to become negative.
2268    __ neg(ecx);
2269    __ add(ecx, esp);
2270    __ sar(ecx, kPointerSizeLog2);
2271    // Check if the arguments will overflow the stack.
2272    __ cmp(ecx, ebx);
2273    __ j(greater, &done, Label::kNear);  // Signed comparison.
2274    __ TailCallRuntime(Runtime::kThrowStackOverflow);
2275    __ bind(&done);
2276  }
2277
2278  // ----------- S t a t e -------------
2279  //  -- edi    : target
2280  //  -- eax    : args (a FixedArray built from argumentsList)
2281  //  -- ebx    : len (number of elements to push from args)
2282  //  -- edx    : new.target (checked to be constructor or undefined)
2283  //  -- esp[0] : return address.
2284  //  -- esp[4] : thisArgument
2285  // -----------------------------------
2286
2287  // Push arguments onto the stack (thisArgument is already on the stack).
2288  {
2289    __ movd(xmm0, edx);
2290    __ PopReturnAddressTo(edx);
2291    __ Move(ecx, Immediate(0));
2292    Label done, loop;
2293    __ bind(&loop);
2294    __ cmp(ecx, ebx);
2295    __ j(equal, &done, Label::kNear);
2296    __ Push(
2297        FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
2298    __ inc(ecx);
2299    __ jmp(&loop);
2300    __ bind(&done);
2301    __ PushReturnAddressFrom(edx);
2302    __ movd(edx, xmm0);
2303    __ Move(eax, ebx);
2304  }
2305
2306  // Dispatch to Call or Construct depending on whether new.target is undefined.
2307  {
2308    __ CompareRoot(edx, Heap::kUndefinedValueRootIndex);
2309    __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2310    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2311  }
2312}
2313
2314namespace {
2315
2316// Drops top JavaScript frame and an arguments adaptor frame below it (if
2317// present) preserving all the arguments prepared for current call.
2318// Does nothing if debugger is currently active.
2319// ES6 14.6.3. PrepareForTailCall
2320//
2321// Stack structure for the function g() tail calling f():
2322//
2323// ------- Caller frame: -------
2324// |  ...
2325// |  g()'s arg M
2326// |  ...
2327// |  g()'s arg 1
2328// |  g()'s receiver arg
2329// |  g()'s caller pc
2330// ------- g()'s frame: -------
2331// |  g()'s caller fp      <- fp
2332// |  g()'s context
2333// |  function pointer: g
2334// |  -------------------------
2335// |  ...
2336// |  ...
2337// |  f()'s arg N
2338// |  ...
2339// |  f()'s arg 1
2340// |  f()'s receiver arg
2341// |  f()'s caller pc      <- sp
2342// ----------------------
2343//
2344void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
2345                        Register scratch1, Register scratch2,
2346                        Register scratch3) {
2347  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
2348  Comment cmnt(masm, "[ PrepareForTailCall");
2349
2350  // Prepare for tail call only if ES2015 tail call elimination is enabled.
2351  Label done;
2352  ExternalReference is_tail_call_elimination_enabled =
2353      ExternalReference::is_tail_call_elimination_enabled_address(
2354          masm->isolate());
2355  __ movzx_b(scratch1,
2356             Operand::StaticVariable(is_tail_call_elimination_enabled));
2357  __ cmp(scratch1, Immediate(0));
2358  __ j(equal, &done, Label::kNear);
2359
2360  // Drop possible interpreter handler/stub frame.
2361  {
2362    Label no_interpreter_frame;
2363    __ cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset),
2364           Immediate(Smi::FromInt(StackFrame::STUB)));
2365    __ j(not_equal, &no_interpreter_frame, Label::kNear);
2366    __ mov(ebp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2367    __ bind(&no_interpreter_frame);
2368  }
2369
2370  // Check if next frame is an arguments adaptor frame.
2371  Register caller_args_count_reg = scratch1;
2372  Label no_arguments_adaptor, formal_parameter_count_loaded;
2373  __ mov(scratch2, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
2374  __ cmp(Operand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset),
2375         Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2376  __ j(not_equal, &no_arguments_adaptor, Label::kNear);
2377
2378  // Drop current frame and load arguments count from arguments adaptor frame.
2379  __ mov(ebp, scratch2);
2380  __ mov(caller_args_count_reg,
2381         Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
2382  __ SmiUntag(caller_args_count_reg);
2383  __ jmp(&formal_parameter_count_loaded, Label::kNear);
2384
2385  __ bind(&no_arguments_adaptor);
2386  // Load caller's formal parameter count
2387  __ mov(scratch1, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
2388  __ mov(scratch1,
2389         FieldOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
2390  __ mov(
2391      caller_args_count_reg,
2392      FieldOperand(scratch1, SharedFunctionInfo::kFormalParameterCountOffset));
2393  __ SmiUntag(caller_args_count_reg);
2394
2395  __ bind(&formal_parameter_count_loaded);
2396
2397  ParameterCount callee_args_count(args_reg);
2398  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
2399                        scratch3, ReturnAddressState::kOnStack, 0);
2400  __ bind(&done);
2401}
2402}  // namespace
2403
2404// static
2405void Builtins::Generate_CallFunction(MacroAssembler* masm,
2406                                     ConvertReceiverMode mode,
2407                                     TailCallMode tail_call_mode) {
2408  // ----------- S t a t e -------------
2409  //  -- eax : the number of arguments (not including the receiver)
2410  //  -- edi : the function to call (checked to be a JSFunction)
2411  // -----------------------------------
2412  __ AssertFunction(edi);
2413
2414  // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
2415  // Check that the function is not a "classConstructor".
2416  Label class_constructor;
2417  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2418  __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
2419            Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte));
2420  __ j(not_zero, &class_constructor);
2421
2422  // Enter the context of the function; ToObject has to run in the function
2423  // context, and we also need to take the global proxy from the function
2424  // context in case of conversion.
2425  STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
2426                SharedFunctionInfo::kStrictModeByteOffset);
2427  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2428  // We need to convert the receiver for non-native sloppy mode functions.
2429  Label done_convert;
2430  __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
2431            Immediate((1 << SharedFunctionInfo::kNativeBitWithinByte) |
2432                      (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
2433  __ j(not_zero, &done_convert);
2434  {
2435    // ----------- S t a t e -------------
2436    //  -- eax : the number of arguments (not including the receiver)
2437    //  -- edx : the shared function info.
2438    //  -- edi : the function to call (checked to be a JSFunction)
2439    //  -- esi : the function context.
2440    // -----------------------------------
2441
2442    if (mode == ConvertReceiverMode::kNullOrUndefined) {
2443      // Patch receiver to global proxy.
2444      __ LoadGlobalProxy(ecx);
2445    } else {
2446      Label convert_to_object, convert_receiver;
2447      __ mov(ecx, Operand(esp, eax, times_pointer_size, kPointerSize));
2448      __ JumpIfSmi(ecx, &convert_to_object, Label::kNear);
2449      STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2450      __ CmpObjectType(ecx, FIRST_JS_RECEIVER_TYPE, ebx);
2451      __ j(above_equal, &done_convert);
2452      if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
2453        Label convert_global_proxy;
2454        __ JumpIfRoot(ecx, Heap::kUndefinedValueRootIndex,
2455                      &convert_global_proxy, Label::kNear);
2456        __ JumpIfNotRoot(ecx, Heap::kNullValueRootIndex, &convert_to_object,
2457                         Label::kNear);
2458        __ bind(&convert_global_proxy);
2459        {
2460          // Patch receiver to global proxy.
2461          __ LoadGlobalProxy(ecx);
2462        }
2463        __ jmp(&convert_receiver);
2464      }
2465      __ bind(&convert_to_object);
2466      {
2467        // Convert receiver using ToObject.
2468        // TODO(bmeurer): Inline the allocation here to avoid building the frame
2469        // in the fast case? (fall back to AllocateInNewSpace?)
2470        FrameScope scope(masm, StackFrame::INTERNAL);
2471        __ SmiTag(eax);
2472        __ Push(eax);
2473        __ Push(edi);
2474        __ mov(eax, ecx);
2475        __ Push(esi);
2476        __ Call(masm->isolate()->builtins()->ToObject(),
2477                RelocInfo::CODE_TARGET);
2478        __ Pop(esi);
2479        __ mov(ecx, eax);
2480        __ Pop(edi);
2481        __ Pop(eax);
2482        __ SmiUntag(eax);
2483      }
2484      __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2485      __ bind(&convert_receiver);
2486    }
2487    __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ecx);
2488  }
2489  __ bind(&done_convert);
2490
2491  // ----------- S t a t e -------------
2492  //  -- eax : the number of arguments (not including the receiver)
2493  //  -- edx : the shared function info.
2494  //  -- edi : the function to call (checked to be a JSFunction)
2495  //  -- esi : the function context.
2496  // -----------------------------------
2497
2498  if (tail_call_mode == TailCallMode::kAllow) {
2499    PrepareForTailCall(masm, eax, ebx, ecx, edx);
2500    // Reload shared function info.
2501    __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2502  }
2503
2504  __ mov(ebx,
2505         FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
2506  __ SmiUntag(ebx);
2507  ParameterCount actual(eax);
2508  ParameterCount expected(ebx);
2509  __ InvokeFunctionCode(edi, no_reg, expected, actual, JUMP_FUNCTION,
2510                        CheckDebugStepCallWrapper());
2511  // The function is a "classConstructor", need to raise an exception.
2512  __ bind(&class_constructor);
2513  {
2514    FrameScope frame(masm, StackFrame::INTERNAL);
2515    __ push(edi);
2516    __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
2517  }
2518}
2519
2520namespace {
2521
2522void Generate_PushBoundArguments(MacroAssembler* masm) {
2523  // ----------- S t a t e -------------
2524  //  -- eax : the number of arguments (not including the receiver)
2525  //  -- edx : new.target (only in case of [[Construct]])
2526  //  -- edi : target (checked to be a JSBoundFunction)
2527  // -----------------------------------
2528
2529  // Load [[BoundArguments]] into ecx and length of that into ebx.
2530  Label no_bound_arguments;
2531  __ mov(ecx, FieldOperand(edi, JSBoundFunction::kBoundArgumentsOffset));
2532  __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
2533  __ SmiUntag(ebx);
2534  __ test(ebx, ebx);
2535  __ j(zero, &no_bound_arguments);
2536  {
2537    // ----------- S t a t e -------------
2538    //  -- eax : the number of arguments (not including the receiver)
2539    //  -- edx : new.target (only in case of [[Construct]])
2540    //  -- edi : target (checked to be a JSBoundFunction)
2541    //  -- ecx : the [[BoundArguments]] (implemented as FixedArray)
2542    //  -- ebx : the number of [[BoundArguments]]
2543    // -----------------------------------
2544
2545    // Reserve stack space for the [[BoundArguments]].
2546    {
2547      Label done;
2548      __ lea(ecx, Operand(ebx, times_pointer_size, 0));
2549      __ sub(esp, ecx);
2550      // Check the stack for overflow. We are not trying to catch interruptions
2551      // (i.e. debug break and preemption) here, so check the "real stack
2552      // limit".
2553      __ CompareRoot(esp, ecx, Heap::kRealStackLimitRootIndex);
2554      __ j(greater, &done, Label::kNear);  // Signed comparison.
2555      // Restore the stack pointer.
2556      __ lea(esp, Operand(esp, ebx, times_pointer_size, 0));
2557      {
2558        FrameScope scope(masm, StackFrame::MANUAL);
2559        __ EnterFrame(StackFrame::INTERNAL);
2560        __ CallRuntime(Runtime::kThrowStackOverflow);
2561      }
2562      __ bind(&done);
2563    }
2564
2565    // Adjust effective number of arguments to include return address.
2566    __ inc(eax);
2567
2568    // Relocate arguments and return address down the stack.
2569    {
2570      Label loop;
2571      __ Set(ecx, 0);
2572      __ lea(ebx, Operand(esp, ebx, times_pointer_size, 0));
2573      __ bind(&loop);
2574      __ movd(xmm0, Operand(ebx, ecx, times_pointer_size, 0));
2575      __ movd(Operand(esp, ecx, times_pointer_size, 0), xmm0);
2576      __ inc(ecx);
2577      __ cmp(ecx, eax);
2578      __ j(less, &loop);
2579    }
2580
2581    // Copy [[BoundArguments]] to the stack (below the arguments).
2582    {
2583      Label loop;
2584      __ mov(ecx, FieldOperand(edi, JSBoundFunction::kBoundArgumentsOffset));
2585      __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
2586      __ SmiUntag(ebx);
2587      __ bind(&loop);
2588      __ dec(ebx);
2589      __ movd(xmm0, FieldOperand(ecx, ebx, times_pointer_size,
2590                                 FixedArray::kHeaderSize));
2591      __ movd(Operand(esp, eax, times_pointer_size, 0), xmm0);
2592      __ lea(eax, Operand(eax, 1));
2593      __ j(greater, &loop);
2594    }
2595
2596    // Adjust effective number of arguments (eax contains the number of
2597    // arguments from the call plus return address plus the number of
2598    // [[BoundArguments]]), so we need to subtract one for the return address.
2599    __ dec(eax);
2600  }
2601  __ bind(&no_bound_arguments);
2602}
2603
2604}  // namespace
2605
2606// static
2607void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
2608                                              TailCallMode tail_call_mode) {
2609  // ----------- S t a t e -------------
2610  //  -- eax : the number of arguments (not including the receiver)
2611  //  -- edi : the function to call (checked to be a JSBoundFunction)
2612  // -----------------------------------
2613  __ AssertBoundFunction(edi);
2614
2615  if (tail_call_mode == TailCallMode::kAllow) {
2616    PrepareForTailCall(masm, eax, ebx, ecx, edx);
2617  }
2618
2619  // Patch the receiver to [[BoundThis]].
2620  __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset));
2621  __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx);
2622
2623  // Push the [[BoundArguments]] onto the stack.
2624  Generate_PushBoundArguments(masm);
2625
2626  // Call the [[BoundTargetFunction]] via the Call builtin.
2627  __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2628  __ mov(ecx, Operand::StaticVariable(ExternalReference(
2629                  Builtins::kCall_ReceiverIsAny, masm->isolate())));
2630  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2631  __ jmp(ecx);
2632}
2633
2634// static
2635void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
2636                             TailCallMode tail_call_mode) {
2637  // ----------- S t a t e -------------
2638  //  -- eax : the number of arguments (not including the receiver)
2639  //  -- edi : the target to call (can be any Object).
2640  // -----------------------------------
2641
2642  Label non_callable, non_function, non_smi;
2643  __ JumpIfSmi(edi, &non_callable);
2644  __ bind(&non_smi);
2645  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2646  __ j(equal, masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
2647       RelocInfo::CODE_TARGET);
2648  __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2649  __ j(equal, masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
2650       RelocInfo::CODE_TARGET);
2651
2652  // Check if target has a [[Call]] internal method.
2653  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2654            Immediate(1 << Map::kIsCallable));
2655  __ j(zero, &non_callable);
2656
2657  __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2658  __ j(not_equal, &non_function);
2659
2660  // 0. Prepare for tail call if necessary.
2661  if (tail_call_mode == TailCallMode::kAllow) {
2662    PrepareForTailCall(masm, eax, ebx, ecx, edx);
2663  }
2664
2665  // 1. Runtime fallback for Proxy [[Call]].
2666  __ PopReturnAddressTo(ecx);
2667  __ Push(edi);
2668  __ PushReturnAddressFrom(ecx);
2669  // Increase the arguments size to include the pushed function and the
2670  // existing receiver on the stack.
2671  __ add(eax, Immediate(2));
2672  // Tail-call to the runtime.
2673  __ JumpToExternalReference(
2674      ExternalReference(Runtime::kJSProxyCall, masm->isolate()));
2675
2676  // 2. Call to something else, which might have a [[Call]] internal method (if
2677  // not we raise an exception).
2678  __ bind(&non_function);
2679  // Overwrite the original receiver with the (original) target.
2680  __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
2681  // Let the "call_as_function_delegate" take care of the rest.
2682  __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, edi);
2683  __ Jump(masm->isolate()->builtins()->CallFunction(
2684              ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode),
2685          RelocInfo::CODE_TARGET);
2686
2687  // 3. Call to something that is not callable.
2688  __ bind(&non_callable);
2689  {
2690    FrameScope scope(masm, StackFrame::INTERNAL);
2691    __ Push(edi);
2692    __ CallRuntime(Runtime::kThrowCalledNonCallable);
2693  }
2694}
2695
2696// static
2697void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2698  // ----------- S t a t e -------------
2699  //  -- eax : the number of arguments (not including the receiver)
2700  //  -- edx : the new target (checked to be a constructor)
2701  //  -- edi : the constructor to call (checked to be a JSFunction)
2702  // -----------------------------------
2703  __ AssertFunction(edi);
2704
2705  // Calling convention for function specific ConstructStubs require
2706  // ebx to contain either an AllocationSite or undefined.
2707  __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
2708
2709  // Tail call to the function-specific construct stub (still in the caller
2710  // context at this point).
2711  __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2712  __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
2713  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2714  __ jmp(ecx);
2715}
2716
2717// static
2718void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2719  // ----------- S t a t e -------------
2720  //  -- eax : the number of arguments (not including the receiver)
2721  //  -- edx : the new target (checked to be a constructor)
2722  //  -- edi : the constructor to call (checked to be a JSBoundFunction)
2723  // -----------------------------------
2724  __ AssertBoundFunction(edi);
2725
2726  // Push the [[BoundArguments]] onto the stack.
2727  Generate_PushBoundArguments(masm);
2728
2729  // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2730  {
2731    Label done;
2732    __ cmp(edi, edx);
2733    __ j(not_equal, &done, Label::kNear);
2734    __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2735    __ bind(&done);
2736  }
2737
2738  // Construct the [[BoundTargetFunction]] via the Construct builtin.
2739  __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2740  __ mov(ecx, Operand::StaticVariable(
2741                  ExternalReference(Builtins::kConstruct, masm->isolate())));
2742  __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2743  __ jmp(ecx);
2744}
2745
2746// static
2747void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2748  // ----------- S t a t e -------------
2749  //  -- eax : the number of arguments (not including the receiver)
2750  //  -- edi : the constructor to call (checked to be a JSProxy)
2751  //  -- edx : the new target (either the same as the constructor or
2752  //           the JSFunction on which new was invoked initially)
2753  // -----------------------------------
2754
2755  // Call into the Runtime for Proxy [[Construct]].
2756  __ PopReturnAddressTo(ecx);
2757  __ Push(edi);
2758  __ Push(edx);
2759  __ PushReturnAddressFrom(ecx);
2760  // Include the pushed new_target, constructor and the receiver.
2761  __ add(eax, Immediate(3));
2762  // Tail-call to the runtime.
2763  __ JumpToExternalReference(
2764      ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2765}
2766
2767// static
2768void Builtins::Generate_Construct(MacroAssembler* masm) {
2769  // ----------- S t a t e -------------
2770  //  -- eax : the number of arguments (not including the receiver)
2771  //  -- edx : the new target (either the same as the constructor or
2772  //           the JSFunction on which new was invoked initially)
2773  //  -- edi : the constructor to call (can be any Object)
2774  // -----------------------------------
2775
2776  // Check if target is a Smi.
2777  Label non_constructor;
2778  __ JumpIfSmi(edi, &non_constructor, Label::kNear);
2779
2780  // Dispatch based on instance type.
2781  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2782  __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2783       RelocInfo::CODE_TARGET);
2784
2785  // Check if target has a [[Construct]] internal method.
2786  __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2787            Immediate(1 << Map::kIsConstructor));
2788  __ j(zero, &non_constructor, Label::kNear);
2789
2790  // Only dispatch to bound functions after checking whether they are
2791  // constructors.
2792  __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2793  __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2794       RelocInfo::CODE_TARGET);
2795
2796  // Only dispatch to proxies after checking whether they are constructors.
2797  __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2798  __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
2799       RelocInfo::CODE_TARGET);
2800
2801  // Called Construct on an exotic Object with a [[Construct]] internal method.
2802  {
2803    // Overwrite the original receiver with the (original) target.
2804    __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
2805    // Let the "call_as_constructor_delegate" take care of the rest.
2806    __ LoadGlobalFunction(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, edi);
2807    __ Jump(masm->isolate()->builtins()->CallFunction(),
2808            RelocInfo::CODE_TARGET);
2809  }
2810
2811  // Called Construct on an Object that doesn't have a [[Construct]] internal
2812  // method.
2813  __ bind(&non_constructor);
2814  __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2815          RelocInfo::CODE_TARGET);
2816}
2817
2818// static
2819void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
2820  // ----------- S t a t e -------------
2821  //  -- edx    : requested object size (untagged)
2822  //  -- esp[0] : return address
2823  // -----------------------------------
2824  __ SmiTag(edx);
2825  __ PopReturnAddressTo(ecx);
2826  __ Push(edx);
2827  __ PushReturnAddressFrom(ecx);
2828  __ Move(esi, Smi::kZero);
2829  __ TailCallRuntime(Runtime::kAllocateInNewSpace);
2830}
2831
2832// static
2833void Builtins::Generate_AllocateInOldSpace(MacroAssembler* masm) {
2834  // ----------- S t a t e -------------
2835  //  -- edx    : requested object size (untagged)
2836  //  -- esp[0] : return address
2837  // -----------------------------------
2838  __ SmiTag(edx);
2839  __ PopReturnAddressTo(ecx);
2840  __ Push(edx);
2841  __ Push(Smi::FromInt(AllocateTargetSpace::encode(OLD_SPACE)));
2842  __ PushReturnAddressFrom(ecx);
2843  __ Move(esi, Smi::kZero);
2844  __ TailCallRuntime(Runtime::kAllocateInTargetSpace);
2845}
2846
2847// static
2848void Builtins::Generate_Abort(MacroAssembler* masm) {
2849  // ----------- S t a t e -------------
2850  //  -- edx    : message_id as Smi
2851  //  -- esp[0] : return address
2852  // -----------------------------------
2853  __ PopReturnAddressTo(ecx);
2854  __ Push(edx);
2855  __ PushReturnAddressFrom(ecx);
2856  __ Move(esi, Smi::kZero);
2857  __ TailCallRuntime(Runtime::kAbort);
2858}
2859
2860void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
2861  // ----------- S t a t e -------------
2862  //  -- eax : actual number of arguments
2863  //  -- ebx : expected number of arguments
2864  //  -- edx : new target (passed through to callee)
2865  //  -- edi : function (passed through to callee)
2866  // -----------------------------------
2867
2868  Label invoke, dont_adapt_arguments, stack_overflow;
2869  __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
2870
2871  Label enough, too_few;
2872  __ cmp(eax, ebx);
2873  __ j(less, &too_few);
2874  __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
2875  __ j(equal, &dont_adapt_arguments);
2876
2877  {  // Enough parameters: Actual >= expected.
2878    __ bind(&enough);
2879    EnterArgumentsAdaptorFrame(masm);
2880    // edi is used as a scratch register. It should be restored from the frame
2881    // when needed.
2882    Generate_StackOverflowCheck(masm, ebx, ecx, edi, &stack_overflow);
2883
2884    // Copy receiver and all expected arguments.
2885    const int offset = StandardFrameConstants::kCallerSPOffset;
2886    __ lea(edi, Operand(ebp, eax, times_4, offset));
2887    __ mov(eax, -1);  // account for receiver
2888
2889    Label copy;
2890    __ bind(&copy);
2891    __ inc(eax);
2892    __ push(Operand(edi, 0));
2893    __ sub(edi, Immediate(kPointerSize));
2894    __ cmp(eax, ebx);
2895    __ j(less, &copy);
2896    // eax now contains the expected number of arguments.
2897    __ jmp(&invoke);
2898  }
2899
2900  {  // Too few parameters: Actual < expected.
2901    __ bind(&too_few);
2902    EnterArgumentsAdaptorFrame(masm);
2903    // edi is used as a scratch register. It should be restored from the frame
2904    // when needed.
2905    Generate_StackOverflowCheck(masm, ebx, ecx, edi, &stack_overflow);
2906
2907    // Remember expected arguments in ecx.
2908    __ mov(ecx, ebx);
2909
2910    // Copy receiver and all actual arguments.
2911    const int offset = StandardFrameConstants::kCallerSPOffset;
2912    __ lea(edi, Operand(ebp, eax, times_4, offset));
2913    // ebx = expected - actual.
2914    __ sub(ebx, eax);
2915    // eax = -actual - 1
2916    __ neg(eax);
2917    __ sub(eax, Immediate(1));
2918
2919    Label copy;
2920    __ bind(&copy);
2921    __ inc(eax);
2922    __ push(Operand(edi, 0));
2923    __ sub(edi, Immediate(kPointerSize));
2924    __ test(eax, eax);
2925    __ j(not_zero, &copy);
2926
2927    // Fill remaining expected arguments with undefined values.
2928    Label fill;
2929    __ bind(&fill);
2930    __ inc(eax);
2931    __ push(Immediate(masm->isolate()->factory()->undefined_value()));
2932    __ cmp(eax, ebx);
2933    __ j(less, &fill);
2934
2935    // Restore expected arguments.
2936    __ mov(eax, ecx);
2937  }
2938
2939  // Call the entry point.
2940  __ bind(&invoke);
2941  // Restore function pointer.
2942  __ mov(edi, Operand(ebp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
2943  // eax : expected number of arguments
2944  // edx : new target (passed through to callee)
2945  // edi : function (passed through to callee)
2946  __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
2947  __ call(ecx);
2948
2949  // Store offset of return address for deoptimizer.
2950  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
2951
2952  // Leave frame and return.
2953  LeaveArgumentsAdaptorFrame(masm);
2954  __ ret(0);
2955
2956  // -------------------------------------------
2957  // Dont adapt arguments.
2958  // -------------------------------------------
2959  __ bind(&dont_adapt_arguments);
2960  __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
2961  __ jmp(ecx);
2962
2963  __ bind(&stack_overflow);
2964  {
2965    FrameScope frame(masm, StackFrame::MANUAL);
2966    __ CallRuntime(Runtime::kThrowStackOverflow);
2967    __ int3();
2968  }
2969}
2970
2971static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
2972                                    Register function_template_info,
2973                                    Register scratch0, Register scratch1,
2974                                    Label* receiver_check_failed) {
2975  // If there is no signature, return the holder.
2976  __ CompareRoot(FieldOperand(function_template_info,
2977                              FunctionTemplateInfo::kSignatureOffset),
2978                 Heap::kUndefinedValueRootIndex);
2979  Label receiver_check_passed;
2980  __ j(equal, &receiver_check_passed, Label::kNear);
2981
2982  // Walk the prototype chain.
2983  __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
2984  Label prototype_loop_start;
2985  __ bind(&prototype_loop_start);
2986
2987  // Get the constructor, if any.
2988  __ GetMapConstructor(scratch0, scratch0, scratch1);
2989  __ CmpInstanceType(scratch1, JS_FUNCTION_TYPE);
2990  Label next_prototype;
2991  __ j(not_equal, &next_prototype, Label::kNear);
2992
2993  // Get the constructor's signature.
2994  __ mov(scratch0,
2995         FieldOperand(scratch0, JSFunction::kSharedFunctionInfoOffset));
2996  __ mov(scratch0,
2997         FieldOperand(scratch0, SharedFunctionInfo::kFunctionDataOffset));
2998
2999  // Loop through the chain of inheriting function templates.
3000  Label function_template_loop;
3001  __ bind(&function_template_loop);
3002
3003  // If the signatures match, we have a compatible receiver.
3004  __ cmp(scratch0, FieldOperand(function_template_info,
3005                                FunctionTemplateInfo::kSignatureOffset));
3006  __ j(equal, &receiver_check_passed, Label::kNear);
3007
3008  // If the current type is not a FunctionTemplateInfo, load the next prototype
3009  // in the chain.
3010  __ JumpIfSmi(scratch0, &next_prototype, Label::kNear);
3011  __ CmpObjectType(scratch0, FUNCTION_TEMPLATE_INFO_TYPE, scratch1);
3012  __ j(not_equal, &next_prototype, Label::kNear);
3013
3014  // Otherwise load the parent function template and iterate.
3015  __ mov(scratch0,
3016         FieldOperand(scratch0, FunctionTemplateInfo::kParentTemplateOffset));
3017  __ jmp(&function_template_loop, Label::kNear);
3018
3019  // Load the next prototype.
3020  __ bind(&next_prototype);
3021  __ mov(receiver, FieldOperand(receiver, HeapObject::kMapOffset));
3022  __ test(FieldOperand(receiver, Map::kBitField3Offset),
3023          Immediate(Map::HasHiddenPrototype::kMask));
3024  __ j(zero, receiver_check_failed);
3025
3026  __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset));
3027  __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
3028  // Iterate.
3029  __ jmp(&prototype_loop_start, Label::kNear);
3030
3031  __ bind(&receiver_check_passed);
3032}
3033
3034void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
3035  // ----------- S t a t e -------------
3036  //  -- eax                : number of arguments (not including the receiver)
3037  //  -- edi                : callee
3038  //  -- esi                : context
3039  //  -- esp[0]             : return address
3040  //  -- esp[4]             : last argument
3041  //  -- ...
3042  //  -- esp[eax * 4]       : first argument
3043  //  -- esp[(eax + 1) * 4] : receiver
3044  // -----------------------------------
3045
3046  // Load the FunctionTemplateInfo.
3047  __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
3048  __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset));
3049
3050  // Do the compatible receiver check.
3051  Label receiver_check_failed;
3052  __ mov(ecx, Operand(esp, eax, times_pointer_size, kPCOnStackSize));
3053  __ Push(eax);
3054  CompatibleReceiverCheck(masm, ecx, ebx, edx, eax, &receiver_check_failed);
3055  __ Pop(eax);
3056  // Get the callback offset from the FunctionTemplateInfo, and jump to the
3057  // beginning of the code.
3058  __ mov(edx, FieldOperand(ebx, FunctionTemplateInfo::kCallCodeOffset));
3059  __ mov(edx, FieldOperand(edx, CallHandlerInfo::kFastHandlerOffset));
3060  __ add(edx, Immediate(Code::kHeaderSize - kHeapObjectTag));
3061  __ jmp(edx);
3062
3063  // Compatible receiver check failed: pop return address, arguments and
3064  // receiver and throw an Illegal Invocation exception.
3065  __ bind(&receiver_check_failed);
3066  __ Pop(eax);
3067  __ PopReturnAddressTo(ebx);
3068  __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize));
3069  __ add(esp, eax);
3070  __ PushReturnAddressFrom(ebx);
3071  {
3072    FrameScope scope(masm, StackFrame::INTERNAL);
3073    __ TailCallRuntime(Runtime::kThrowIllegalInvocation);
3074  }
3075}
3076
3077static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
3078                                              bool has_handler_frame) {
3079  // Lookup the function in the JavaScript frame.
3080  if (has_handler_frame) {
3081    __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
3082    __ mov(eax, Operand(eax, JavaScriptFrameConstants::kFunctionOffset));
3083  } else {
3084    __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
3085  }
3086
3087  {
3088    FrameScope scope(masm, StackFrame::INTERNAL);
3089    // Pass function as argument.
3090    __ push(eax);
3091    __ CallRuntime(Runtime::kCompileForOnStackReplacement);
3092  }
3093
3094  Label skip;
3095  // If the code object is null, just return to the caller.
3096  __ cmp(eax, Immediate(0));
3097  __ j(not_equal, &skip, Label::kNear);
3098  __ ret(0);
3099
3100  __ bind(&skip);
3101
3102  // Drop any potential handler frame that is be sitting on top of the actual
3103  // JavaScript frame. This is the case then OSR is triggered from bytecode.
3104  if (has_handler_frame) {
3105    __ leave();
3106  }
3107
3108  // Load deoptimization data from the code object.
3109  __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag));
3110
3111  // Load the OSR entrypoint offset from the deoptimization data.
3112  __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt(
3113                               DeoptimizationInputData::kOsrPcOffsetIndex) -
3114                               kHeapObjectTag));
3115  __ SmiUntag(ebx);
3116
3117  // Compute the target address = code_obj + header_size + osr_offset
3118  __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag));
3119
3120  // Overwrite the return address on the stack.
3121  __ mov(Operand(esp, 0), eax);
3122
3123  // And "return" to the OSR entry point of the function.
3124  __ ret(0);
3125}
3126
3127void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
3128  Generate_OnStackReplacementHelper(masm, false);
3129}
3130
3131void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3132  Generate_OnStackReplacementHelper(masm, true);
3133}
3134
3135#undef __
3136}  // namespace internal
3137}  // namespace v8
3138
3139#endif  // V8_TARGET_ARCH_IA32
3140