Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 1701983004: X87: [runtime] Turn ArgumentAccessStub into FastNewSloppyArgumentsStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 422
423 StubRuntimeCallHelper call_helper; 423 StubRuntimeCallHelper call_helper;
424 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); 424 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper);
425 425
426 __ bind(&miss); 426 __ bind(&miss);
427 PropertyAccessCompiler::TailCallBuiltin( 427 PropertyAccessCompiler::TailCallBuiltin(
428 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); 428 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
429 } 429 }
430 430
431 431
432 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
433 // ecx : number of parameters (tagged)
434 // edx : parameters pointer
435 // edi : function
436 // esp[0] : return address
437
438 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
439 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
440 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
441
442 // Check if the calling frame is an arguments adaptor frame.
443 Label runtime;
444 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
445 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
446 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
447 __ j(not_equal, &runtime, Label::kNear);
448
449 // Patch the arguments.length and the parameters pointer.
450 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
451 __ lea(edx,
452 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
453
454 __ bind(&runtime);
455 __ pop(eax); // Pop return address.
456 __ push(edi); // Push function.
457 __ push(edx); // Push parameters pointer.
458 __ push(ecx); // Push parameter count.
459 __ push(eax); // Push return address.
460 __ TailCallRuntime(Runtime::kNewSloppyArguments);
461 }
462
463
464 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
465 // ecx : number of parameters (tagged)
466 // edx : parameters pointer
467 // edi : function
468 // esp[0] : return address
469
470 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
471 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
472 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
473
474 // Check if the calling frame is an arguments adaptor frame.
475 Label adaptor_frame, try_allocate, runtime;
476 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
477 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
478 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
479 __ j(equal, &adaptor_frame, Label::kNear);
480
481 // No adaptor, parameter count = argument count.
482 __ mov(ebx, ecx);
483 __ push(ecx);
484 __ jmp(&try_allocate, Label::kNear);
485
486 // We have an adaptor frame. Patch the parameters pointer.
487 __ bind(&adaptor_frame);
488 __ mov(ebx, ecx);
489 __ push(ecx);
490 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
491 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
492 __ lea(edx, Operand(edx, ecx, times_2,
493 StandardFrameConstants::kCallerSPOffset));
494
495 // ebx = parameter count (tagged)
496 // ecx = argument count (smi-tagged)
497 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
498 __ cmp(ebx, ecx);
499 __ j(less_equal, &try_allocate, Label::kNear);
500 __ mov(ebx, ecx);
501
502 // Save mapped parameter count and function.
503 __ bind(&try_allocate);
504 __ push(edi);
505 __ push(ebx);
506
507 // Compute the sizes of backing store, parameter map, and arguments object.
508 // 1. Parameter map, has 2 extra words containing context and backing store.
509 const int kParameterMapHeaderSize =
510 FixedArray::kHeaderSize + 2 * kPointerSize;
511 Label no_parameter_map;
512 __ test(ebx, ebx);
513 __ j(zero, &no_parameter_map, Label::kNear);
514 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
515 __ bind(&no_parameter_map);
516
517 // 2. Backing store.
518 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
519
520 // 3. Arguments object.
521 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize));
522
523 // Do the allocation of all three objects in one go.
524 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
525
526 // eax = address of new object(s) (tagged)
527 // ecx = argument count (smi-tagged)
528 // esp[0] = mapped parameter count (tagged)
529 // esp[4] = function
530 // esp[8] = parameter count (tagged)
531 // Get the arguments map from the current native context into edi.
532 Label has_mapped_parameters, instantiate;
533 __ mov(edi, NativeContextOperand());
534 __ mov(ebx, Operand(esp, 0 * kPointerSize));
535 __ test(ebx, ebx);
536 __ j(not_zero, &has_mapped_parameters, Label::kNear);
537 __ mov(
538 edi,
539 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
540 __ jmp(&instantiate, Label::kNear);
541
542 __ bind(&has_mapped_parameters);
543 __ mov(edi, Operand(edi, Context::SlotOffset(
544 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
545 __ bind(&instantiate);
546
547 // eax = address of new object (tagged)
548 // ebx = mapped parameter count (tagged)
549 // ecx = argument count (smi-tagged)
550 // edi = address of arguments map (tagged)
551 // esp[0] = mapped parameter count (tagged)
552 // esp[4] = function
553 // esp[8] = parameter count (tagged)
554 // Copy the JS object part.
555 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
556 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
557 masm->isolate()->factory()->empty_fixed_array());
558 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
559 masm->isolate()->factory()->empty_fixed_array());
560
561 // Set up the callee in-object property.
562 STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1);
563 __ mov(edi, Operand(esp, 1 * kPointerSize));
564 __ AssertNotSmi(edi);
565 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi);
566
567 // Use the length (smi tagged) and set that as an in-object property too.
568 __ AssertSmi(ecx);
569 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx);
570
571 // Set up the elements pointer in the allocated arguments object.
572 // If we allocated a parameter map, edi will point there, otherwise to the
573 // backing store.
574 __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize));
575 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
576
577 // eax = address of new object (tagged)
578 // ebx = mapped parameter count (tagged)
579 // ecx = argument count (tagged)
580 // edx = address of receiver argument
581 // edi = address of parameter map or backing store (tagged)
582 // esp[0] = mapped parameter count (tagged)
583 // esp[4] = function
584 // esp[8] = parameter count (tagged)
585 // Free two registers.
586 __ push(edx);
587 __ push(eax);
588
589 // Initialize parameter map. If there are no mapped arguments, we're done.
590 Label skip_parameter_map;
591 __ test(ebx, ebx);
592 __ j(zero, &skip_parameter_map);
593
594 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
595 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
596 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
597 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
598 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
599 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
600 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
601
602 // Copy the parameter slots and the holes in the arguments.
603 // We need to fill in mapped_parameter_count slots. They index the context,
604 // where parameters are stored in reverse order, at
605 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
606 // The mapped parameter thus need to get indices
607 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
608 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
609 // We loop from right to left.
610 Label parameters_loop, parameters_test;
611 __ push(ecx);
612 __ mov(eax, Operand(esp, 3 * kPointerSize));
613 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
614 __ add(ebx, Operand(esp, 5 * kPointerSize));
615 __ sub(ebx, eax);
616 __ mov(ecx, isolate()->factory()->the_hole_value());
617 __ mov(edx, edi);
618 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
619 // eax = loop variable (tagged)
620 // ebx = mapping index (tagged)
621 // ecx = the hole value
622 // edx = address of parameter map (tagged)
623 // edi = address of backing store (tagged)
624 // esp[0] = argument count (tagged)
625 // esp[4] = address of new object (tagged)
626 // esp[8] = address of receiver argument
627 // esp[12] = mapped parameter count (tagged)
628 // esp[16] = function
629 // esp[20] = parameter count (tagged)
630 __ jmp(&parameters_test, Label::kNear);
631
632 __ bind(&parameters_loop);
633 __ sub(eax, Immediate(Smi::FromInt(1)));
634 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
635 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
636 __ add(ebx, Immediate(Smi::FromInt(1)));
637 __ bind(&parameters_test);
638 __ test(eax, eax);
639 __ j(not_zero, &parameters_loop, Label::kNear);
640 __ pop(ecx);
641
642 __ bind(&skip_parameter_map);
643
644 // ecx = argument count (tagged)
645 // edi = address of backing store (tagged)
646 // esp[0] = address of new object (tagged)
647 // esp[4] = address of receiver argument
648 // esp[8] = mapped parameter count (tagged)
649 // esp[12] = function
650 // esp[16] = parameter count (tagged)
651 // Copy arguments header and remaining slots (if there are any).
652 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
653 Immediate(isolate()->factory()->fixed_array_map()));
654 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
655
656 Label arguments_loop, arguments_test;
657 __ mov(ebx, Operand(esp, 2 * kPointerSize));
658 __ mov(edx, Operand(esp, 1 * kPointerSize));
659 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
660 __ sub(edx, ebx);
661 __ jmp(&arguments_test, Label::kNear);
662
663 __ bind(&arguments_loop);
664 __ sub(edx, Immediate(kPointerSize));
665 __ mov(eax, Operand(edx, 0));
666 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
667 __ add(ebx, Immediate(Smi::FromInt(1)));
668
669 __ bind(&arguments_test);
670 __ cmp(ebx, ecx);
671 __ j(less, &arguments_loop, Label::kNear);
672
673 // Restore.
674 __ pop(eax); // Address of arguments object.
675 __ Drop(4);
676
677 // Return.
678 __ ret(0);
679
680 // Do the runtime call to allocate the arguments object.
681 __ bind(&runtime);
682 __ pop(eax); // Remove saved mapped parameter count.
683 __ pop(edi); // Pop saved function.
684 __ pop(eax); // Remove saved parameter count.
685 __ pop(eax); // Pop return address.
686 __ push(edi); // Push function.
687 __ push(edx); // Push parameters pointer.
688 __ push(ecx); // Push parameter count.
689 __ push(eax); // Push return address.
690 __ TailCallRuntime(Runtime::kNewSloppyArguments);
691 }
692
693
694 void RegExpExecStub::Generate(MacroAssembler* masm) { 432 void RegExpExecStub::Generate(MacroAssembler* masm) {
695 // Just jump directly to runtime if native RegExp is not selected at compile 433 // Just jump directly to runtime if native RegExp is not selected at compile
696 // time or if regexp entry in generated code is turned off runtime switch or 434 // time or if regexp entry in generated code is turned off runtime switch or
697 // at compilation. 435 // at compilation.
698 #ifdef V8_INTERPRETED_REGEXP 436 #ifdef V8_INTERPRETED_REGEXP
699 __ TailCallRuntime(Runtime::kRegExpExec); 437 __ TailCallRuntime(Runtime::kRegExpExec);
700 #else // V8_INTERPRETED_REGEXP 438 #else // V8_INTERPRETED_REGEXP
701 439
702 // Stack frame on entry. 440 // Stack frame on entry.
703 // esp[0]: return address 441 // esp[0]: return address
(...skipping 3519 matching lines...) Expand 10 before | Expand all | Expand 10 after
4223 __ pop(key); 3961 __ pop(key);
4224 __ pop(vector); 3962 __ pop(vector);
4225 __ pop(receiver); 3963 __ pop(receiver);
4226 __ jmp(miss); 3964 __ jmp(miss);
4227 3965
4228 __ bind(&load_smi_map); 3966 __ bind(&load_smi_map);
4229 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); 3967 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4230 __ jmp(&compare_map); 3968 __ jmp(&compare_map);
4231 } 3969 }
4232 3970
4233
4234 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 3971 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4235 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx 3972 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx
4236 Register key = VectorStoreICDescriptor::NameRegister(); // ecx 3973 Register key = VectorStoreICDescriptor::NameRegister(); // ecx
4237 Register value = VectorStoreICDescriptor::ValueRegister(); // eax 3974 Register value = VectorStoreICDescriptor::ValueRegister(); // eax
4238 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx 3975 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx
4239 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi 3976 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi
4240 Label miss; 3977 Label miss;
4241 3978
4242 __ push(value); 3979 __ push(value);
4243 3980
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4279 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 4016 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4280 FixedArray::kHeaderSize + kPointerSize)); 4017 FixedArray::kHeaderSize + kPointerSize));
4281 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false, 4018 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false,
4282 &miss); 4019 &miss);
4283 4020
4284 __ bind(&miss); 4021 __ bind(&miss);
4285 __ pop(value); 4022 __ pop(value);
4286 KeyedStoreIC::GenerateMiss(masm); 4023 KeyedStoreIC::GenerateMiss(masm);
4287 } 4024 }
4288 4025
4289
4290 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4026 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4291 __ EmitLoadTypeFeedbackVector(ebx); 4027 __ EmitLoadTypeFeedbackVector(ebx);
4292 CallICStub stub(isolate(), state()); 4028 CallICStub stub(isolate(), state());
4293 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4029 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4294 } 4030 }
4295 4031
4296
4297 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4032 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4298 if (masm->isolate()->function_entry_hook() != NULL) { 4033 if (masm->isolate()->function_entry_hook() != NULL) {
4299 ProfileEntryHookStub stub(masm->isolate()); 4034 ProfileEntryHookStub stub(masm->isolate());
4300 masm->CallStub(&stub); 4035 masm->CallStub(&stub);
4301 } 4036 }
4302 } 4037 }
4303 4038
4304
4305 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { 4039 void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
4306 // Save volatile registers. 4040 // Save volatile registers.
4307 const int kNumSavedRegisters = 3; 4041 const int kNumSavedRegisters = 3;
4308 __ push(eax); 4042 __ push(eax);
4309 __ push(ecx); 4043 __ push(ecx);
4310 __ push(edx); 4044 __ push(edx);
4311 4045
4312 // Calculate and push the original stack pointer. 4046 // Calculate and push the original stack pointer.
4313 __ lea(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize)); 4047 __ lea(eax, Operand(esp, (kNumSavedRegisters + 1) * kPointerSize));
4314 __ push(eax); 4048 __ push(eax);
(...skipping 11 matching lines...) Expand all
4326 __ add(esp, Immediate(2 * kPointerSize)); 4060 __ add(esp, Immediate(2 * kPointerSize));
4327 4061
4328 // Restore ecx. 4062 // Restore ecx.
4329 __ pop(edx); 4063 __ pop(edx);
4330 __ pop(ecx); 4064 __ pop(ecx);
4331 __ pop(eax); 4065 __ pop(eax);
4332 4066
4333 __ ret(0); 4067 __ ret(0);
4334 } 4068 }
4335 4069
4336 4070 template <class T>
4337 template<class T>
4338 static void CreateArrayDispatch(MacroAssembler* masm, 4071 static void CreateArrayDispatch(MacroAssembler* masm,
4339 AllocationSiteOverrideMode mode) { 4072 AllocationSiteOverrideMode mode) {
4340 if (mode == DISABLE_ALLOCATION_SITES) { 4073 if (mode == DISABLE_ALLOCATION_SITES) {
4341 T stub(masm->isolate(), 4074 T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
4342 GetInitialFastElementsKind(),
4343 mode);
4344 __ TailCallStub(&stub); 4075 __ TailCallStub(&stub);
4345 } else if (mode == DONT_OVERRIDE) { 4076 } else if (mode == DONT_OVERRIDE) {
4346 int last_index = GetSequenceIndexFromFastElementsKind( 4077 int last_index =
4347 TERMINAL_FAST_ELEMENTS_KIND); 4078 GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
4348 for (int i = 0; i <= last_index; ++i) { 4079 for (int i = 0; i <= last_index; ++i) {
4349 Label next; 4080 Label next;
4350 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4081 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4351 __ cmp(edx, kind); 4082 __ cmp(edx, kind);
4352 __ j(not_equal, &next); 4083 __ j(not_equal, &next);
4353 T stub(masm->isolate(), kind); 4084 T stub(masm->isolate(), kind);
4354 __ TailCallStub(&stub); 4085 __ TailCallStub(&stub);
4355 __ bind(&next); 4086 __ bind(&next);
4356 } 4087 }
4357 4088
4358 // If we reached this point there is a problem. 4089 // If we reached this point there is a problem.
4359 __ Abort(kUnexpectedElementsKindInArrayConstructor); 4090 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4360 } else { 4091 } else {
4361 UNREACHABLE(); 4092 UNREACHABLE();
4362 } 4093 }
4363 } 4094 }
4364 4095
4365
4366 static void CreateArrayDispatchOneArgument(MacroAssembler* masm, 4096 static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
4367 AllocationSiteOverrideMode mode) { 4097 AllocationSiteOverrideMode mode) {
4368 // ebx - allocation site (if mode != DISABLE_ALLOCATION_SITES) 4098 // ebx - allocation site (if mode != DISABLE_ALLOCATION_SITES)
4369 // edx - kind (if mode != DISABLE_ALLOCATION_SITES) 4099 // edx - kind (if mode != DISABLE_ALLOCATION_SITES)
4370 // eax - number of arguments 4100 // eax - number of arguments
4371 // edi - constructor? 4101 // edi - constructor?
4372 // esp[0] - return address 4102 // esp[0] - return address
4373 // esp[4] - last argument 4103 // esp[4] - last argument
4374 Label normal_sequence; 4104 Label normal_sequence;
4375 if (mode == DONT_OVERRIDE) { 4105 if (mode == DONT_OVERRIDE) {
(...skipping 11 matching lines...) Expand all
4387 4117
4388 // look at the first argument 4118 // look at the first argument
4389 __ mov(ecx, Operand(esp, kPointerSize)); 4119 __ mov(ecx, Operand(esp, kPointerSize));
4390 __ test(ecx, ecx); 4120 __ test(ecx, ecx);
4391 __ j(zero, &normal_sequence); 4121 __ j(zero, &normal_sequence);
4392 4122
4393 if (mode == DISABLE_ALLOCATION_SITES) { 4123 if (mode == DISABLE_ALLOCATION_SITES) {
4394 ElementsKind initial = GetInitialFastElementsKind(); 4124 ElementsKind initial = GetInitialFastElementsKind();
4395 ElementsKind holey_initial = GetHoleyElementsKind(initial); 4125 ElementsKind holey_initial = GetHoleyElementsKind(initial);
4396 4126
4397 ArraySingleArgumentConstructorStub stub_holey(masm->isolate(), 4127 ArraySingleArgumentConstructorStub stub_holey(
4398 holey_initial, 4128 masm->isolate(), holey_initial, DISABLE_ALLOCATION_SITES);
4399 DISABLE_ALLOCATION_SITES);
4400 __ TailCallStub(&stub_holey); 4129 __ TailCallStub(&stub_holey);
4401 4130
4402 __ bind(&normal_sequence); 4131 __ bind(&normal_sequence);
4403 ArraySingleArgumentConstructorStub stub(masm->isolate(), 4132 ArraySingleArgumentConstructorStub stub(masm->isolate(), initial,
4404 initial,
4405 DISABLE_ALLOCATION_SITES); 4133 DISABLE_ALLOCATION_SITES);
4406 __ TailCallStub(&stub); 4134 __ TailCallStub(&stub);
4407 } else if (mode == DONT_OVERRIDE) { 4135 } else if (mode == DONT_OVERRIDE) {
4408 // We are going to create a holey array, but our kind is non-holey. 4136 // We are going to create a holey array, but our kind is non-holey.
4409 // Fix kind and retry. 4137 // Fix kind and retry.
4410 __ inc(edx); 4138 __ inc(edx);
4411 4139
4412 if (FLAG_debug_code) { 4140 if (FLAG_debug_code) {
4413 Handle<Map> allocation_site_map = 4141 Handle<Map> allocation_site_map =
4414 masm->isolate()->factory()->allocation_site_map(); 4142 masm->isolate()->factory()->allocation_site_map();
4415 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); 4143 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map));
4416 __ Assert(equal, kExpectedAllocationSite); 4144 __ Assert(equal, kExpectedAllocationSite);
4417 } 4145 }
4418 4146
4419 // Save the resulting elements kind in type info. We can't just store r3 4147 // Save the resulting elements kind in type info. We can't just store r3
4420 // in the AllocationSite::transition_info field because elements kind is 4148 // in the AllocationSite::transition_info field because elements kind is
4421 // restricted to a portion of the field...upper bits need to be left alone. 4149 // restricted to a portion of the field...upper bits need to be left alone.
4422 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 4150 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
4423 __ add(FieldOperand(ebx, AllocationSite::kTransitionInfoOffset), 4151 __ add(FieldOperand(ebx, AllocationSite::kTransitionInfoOffset),
4424 Immediate(Smi::FromInt(kFastElementsKindPackedToHoley))); 4152 Immediate(Smi::FromInt(kFastElementsKindPackedToHoley)));
4425 4153
4426 __ bind(&normal_sequence); 4154 __ bind(&normal_sequence);
4427 int last_index = GetSequenceIndexFromFastElementsKind( 4155 int last_index =
4428 TERMINAL_FAST_ELEMENTS_KIND); 4156 GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
4429 for (int i = 0; i <= last_index; ++i) { 4157 for (int i = 0; i <= last_index; ++i) {
4430 Label next; 4158 Label next;
4431 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4159 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4432 __ cmp(edx, kind); 4160 __ cmp(edx, kind);
4433 __ j(not_equal, &next); 4161 __ j(not_equal, &next);
4434 ArraySingleArgumentConstructorStub stub(masm->isolate(), kind); 4162 ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
4435 __ TailCallStub(&stub); 4163 __ TailCallStub(&stub);
4436 __ bind(&next); 4164 __ bind(&next);
4437 } 4165 }
4438 4166
4439 // If we reached this point there is a problem. 4167 // If we reached this point there is a problem.
4440 __ Abort(kUnexpectedElementsKindInArrayConstructor); 4168 __ Abort(kUnexpectedElementsKindInArrayConstructor);
4441 } else { 4169 } else {
4442 UNREACHABLE(); 4170 UNREACHABLE();
4443 } 4171 }
4444 } 4172 }
4445 4173
4446 4174 template <class T>
4447 template<class T>
4448 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { 4175 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
4449 int to_index = GetSequenceIndexFromFastElementsKind( 4176 int to_index =
4450 TERMINAL_FAST_ELEMENTS_KIND); 4177 GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
4451 for (int i = 0; i <= to_index; ++i) { 4178 for (int i = 0; i <= to_index; ++i) {
4452 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 4179 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
4453 T stub(isolate, kind); 4180 T stub(isolate, kind);
4454 stub.GetCode(); 4181 stub.GetCode();
4455 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { 4182 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
4456 T stub1(isolate, kind, DISABLE_ALLOCATION_SITES); 4183 T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
4457 stub1.GetCode(); 4184 stub1.GetCode();
4458 } 4185 }
4459 } 4186 }
4460 } 4187 }
4461 4188
4462
4463 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 4189 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
4464 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 4190 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
4465 isolate); 4191 isolate);
4466 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( 4192 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
4467 isolate); 4193 isolate);
4468 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( 4194 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
4469 isolate); 4195 isolate);
4470 } 4196 }
4471 4197
4472
4473 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime( 4198 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
4474 Isolate* isolate) { 4199 Isolate* isolate) {
4475 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS }; 4200 ElementsKind kinds[2] = {FAST_ELEMENTS, FAST_HOLEY_ELEMENTS};
4476 for (int i = 0; i < 2; i++) { 4201 for (int i = 0; i < 2; i++) {
4477 // For internal arrays we only need a few things 4202 // For internal arrays we only need a few things
4478 InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]); 4203 InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
4479 stubh1.GetCode(); 4204 stubh1.GetCode();
4480 InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]); 4205 InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
4481 stubh2.GetCode(); 4206 stubh2.GetCode();
4482 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]); 4207 InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
4483 stubh3.GetCode(); 4208 stubh3.GetCode();
4484 } 4209 }
4485 } 4210 }
4486 4211
4487
4488 void ArrayConstructorStub::GenerateDispatchToArrayStub( 4212 void ArrayConstructorStub::GenerateDispatchToArrayStub(
4489 MacroAssembler* masm, 4213 MacroAssembler* masm, AllocationSiteOverrideMode mode) {
4490 AllocationSiteOverrideMode mode) {
4491 if (argument_count() == ANY) { 4214 if (argument_count() == ANY) {
4492 Label not_zero_case, not_one_case; 4215 Label not_zero_case, not_one_case;
4493 __ test(eax, eax); 4216 __ test(eax, eax);
4494 __ j(not_zero, &not_zero_case); 4217 __ j(not_zero, &not_zero_case);
4495 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); 4218 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
4496 4219
4497 __ bind(&not_zero_case); 4220 __ bind(&not_zero_case);
4498 __ cmp(eax, 1); 4221 __ cmp(eax, 1);
4499 __ j(greater, &not_one_case); 4222 __ j(greater, &not_one_case);
4500 CreateArrayDispatchOneArgument(masm, mode); 4223 CreateArrayDispatchOneArgument(masm, mode);
4501 4224
4502 __ bind(&not_one_case); 4225 __ bind(&not_one_case);
4503 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); 4226 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
4504 } else if (argument_count() == NONE) { 4227 } else if (argument_count() == NONE) {
4505 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); 4228 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
4506 } else if (argument_count() == ONE) { 4229 } else if (argument_count() == ONE) {
4507 CreateArrayDispatchOneArgument(masm, mode); 4230 CreateArrayDispatchOneArgument(masm, mode);
4508 } else if (argument_count() == MORE_THAN_ONE) { 4231 } else if (argument_count() == MORE_THAN_ONE) {
4509 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); 4232 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
4510 } else { 4233 } else {
4511 UNREACHABLE(); 4234 UNREACHABLE();
4512 } 4235 }
4513 } 4236 }
4514 4237
4515
4516 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 4238 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
4517 // ----------- S t a t e ------------- 4239 // ----------- S t a t e -------------
4518 // -- eax : argc (only if argument_count() is ANY or MORE_THAN_ONE) 4240 // -- eax : argc (only if argument_count() is ANY or MORE_THAN_ONE)
4519 // -- ebx : AllocationSite or undefined 4241 // -- ebx : AllocationSite or undefined
4520 // -- edi : constructor 4242 // -- edi : constructor
4521 // -- edx : Original constructor 4243 // -- edx : Original constructor
4522 // -- esp[0] : return address 4244 // -- esp[0] : return address
4523 // -- esp[4] : last argument 4245 // -- esp[4] : last argument
4524 // ----------------------------------- 4246 // -----------------------------------
4525 if (FLAG_debug_code) { 4247 if (FLAG_debug_code) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4579 __ mov(eax, Immediate(4)); 4301 __ mov(eax, Immediate(4));
4580 break; 4302 break;
4581 } 4303 }
4582 __ PopReturnAddressTo(ecx); 4304 __ PopReturnAddressTo(ecx);
4583 __ Push(edx); 4305 __ Push(edx);
4584 __ Push(ebx); 4306 __ Push(ebx);
4585 __ PushReturnAddressFrom(ecx); 4307 __ PushReturnAddressFrom(ecx);
4586 __ JumpToExternalReference(ExternalReference(Runtime::kNewArray, isolate())); 4308 __ JumpToExternalReference(ExternalReference(Runtime::kNewArray, isolate()));
4587 } 4309 }
4588 4310
4589 4311 void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm,
4590 void InternalArrayConstructorStub::GenerateCase( 4312 ElementsKind kind) {
4591 MacroAssembler* masm, ElementsKind kind) {
4592 Label not_zero_case, not_one_case; 4313 Label not_zero_case, not_one_case;
4593 Label normal_sequence; 4314 Label normal_sequence;
4594 4315
4595 __ test(eax, eax); 4316 __ test(eax, eax);
4596 __ j(not_zero, &not_zero_case); 4317 __ j(not_zero, &not_zero_case);
4597 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind); 4318 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
4598 __ TailCallStub(&stub0); 4319 __ TailCallStub(&stub0);
4599 4320
4600 __ bind(&not_zero_case); 4321 __ bind(&not_zero_case);
4601 __ cmp(eax, 1); 4322 __ cmp(eax, 1);
4602 __ j(greater, &not_one_case); 4323 __ j(greater, &not_one_case);
4603 4324
4604 if (IsFastPackedElementsKind(kind)) { 4325 if (IsFastPackedElementsKind(kind)) {
4605 // We might need to create a holey array 4326 // We might need to create a holey array
4606 // look at the first argument 4327 // look at the first argument
4607 __ mov(ecx, Operand(esp, kPointerSize)); 4328 __ mov(ecx, Operand(esp, kPointerSize));
4608 __ test(ecx, ecx); 4329 __ test(ecx, ecx);
4609 __ j(zero, &normal_sequence); 4330 __ j(zero, &normal_sequence);
4610 4331
4611 InternalArraySingleArgumentConstructorStub 4332 InternalArraySingleArgumentConstructorStub stub1_holey(
4612 stub1_holey(isolate(), GetHoleyElementsKind(kind)); 4333 isolate(), GetHoleyElementsKind(kind));
4613 __ TailCallStub(&stub1_holey); 4334 __ TailCallStub(&stub1_holey);
4614 } 4335 }
4615 4336
4616 __ bind(&normal_sequence); 4337 __ bind(&normal_sequence);
4617 InternalArraySingleArgumentConstructorStub stub1(isolate(), kind); 4338 InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
4618 __ TailCallStub(&stub1); 4339 __ TailCallStub(&stub1);
4619 4340
4620 __ bind(&not_one_case); 4341 __ bind(&not_one_case);
4621 InternalArrayNArgumentsConstructorStub stubN(isolate(), kind); 4342 InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
4622 __ TailCallStub(&stubN); 4343 __ TailCallStub(&stubN);
4623 } 4344 }
4624 4345
4625
4626 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { 4346 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
4627 // ----------- S t a t e ------------- 4347 // ----------- S t a t e -------------
4628 // -- eax : argc 4348 // -- eax : argc
4629 // -- edi : constructor 4349 // -- edi : constructor
4630 // -- esp[0] : return address 4350 // -- esp[0] : return address
4631 // -- esp[4] : last argument 4351 // -- esp[4] : last argument
4632 // ----------------------------------- 4352 // -----------------------------------
4633 4353
4634 if (FLAG_debug_code) { 4354 if (FLAG_debug_code) {
4635 // The array construct code is only set for the global and natives 4355 // The array construct code is only set for the global and natives
(...skipping 15 matching lines...) Expand all
4651 // but the following masking takes care of that anyway. 4371 // but the following masking takes care of that anyway.
4652 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); 4372 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
4653 // Retrieve elements_kind from bit field 2. 4373 // Retrieve elements_kind from bit field 2.
4654 __ DecodeField<Map::ElementsKindBits>(ecx); 4374 __ DecodeField<Map::ElementsKindBits>(ecx);
4655 4375
4656 if (FLAG_debug_code) { 4376 if (FLAG_debug_code) {
4657 Label done; 4377 Label done;
4658 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 4378 __ cmp(ecx, Immediate(FAST_ELEMENTS));
4659 __ j(equal, &done); 4379 __ j(equal, &done);
4660 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS)); 4380 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS));
4661 __ Assert(equal, 4381 __ Assert(equal, kInvalidElementsKindForInternalArrayOrInternalPackedArray);
4662 kInvalidElementsKindForInternalArrayOrInternalPackedArray);
4663 __ bind(&done); 4382 __ bind(&done);
4664 } 4383 }
4665 4384
4666 Label fast_elements_case; 4385 Label fast_elements_case;
4667 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 4386 __ cmp(ecx, Immediate(FAST_ELEMENTS));
4668 __ j(equal, &fast_elements_case); 4387 __ j(equal, &fast_elements_case);
4669 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 4388 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
4670 4389
4671 __ bind(&fast_elements_case); 4390 __ bind(&fast_elements_case);
4672 GenerateCase(masm, FAST_ELEMENTS); 4391 GenerateCase(masm, FAST_ELEMENTS);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
4811 __ Push(ecx); 4530 __ Push(ecx);
4812 __ CallRuntime(Runtime::kAllocateInNewSpace); 4531 __ CallRuntime(Runtime::kAllocateInNewSpace);
4813 __ mov(edx, eax); 4532 __ mov(edx, eax);
4814 __ Pop(ebx); 4533 __ Pop(ebx);
4815 __ Pop(eax); 4534 __ Pop(eax);
4816 } 4535 }
4817 __ jmp(&done_allocate); 4536 __ jmp(&done_allocate);
4818 } 4537 }
4819 } 4538 }
4820 4539
4540 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) {
4541 // ----------- S t a t e -------------
4542 // -- edi : function
4543 // -- esi : context
4544 // -- ebp : frame pointer
4545 // -- esp[0] : return address
4546 // -----------------------------------
4547 __ AssertFunction(edi);
4548
4549 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub.
4550 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
4551 __ mov(ecx,
4552 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
4553 __ lea(edx, Operand(ebp, ecx, times_half_pointer_size,
4554 StandardFrameConstants::kCallerSPOffset));
4555
4556 // ecx : number of parameters (tagged)
4557 // edx : parameters pointer
4558 // edi : function
4559 // esp[0] : return address
4560
4561 // Check if the calling frame is an arguments adaptor frame.
4562 Label adaptor_frame, try_allocate, runtime;
4563 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
4564 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
4565 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4566 __ j(equal, &adaptor_frame, Label::kNear);
4567
4568 // No adaptor, parameter count = argument count.
4569 __ mov(ebx, ecx);
4570 __ push(ecx);
4571 __ jmp(&try_allocate, Label::kNear);
4572
4573 // We have an adaptor frame. Patch the parameters pointer.
4574 __ bind(&adaptor_frame);
4575 __ mov(ebx, ecx);
4576 __ push(ecx);
4577 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
4578 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
4579 __ lea(edx,
4580 Operand(edx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
4581
4582 // ebx = parameter count (tagged)
4583 // ecx = argument count (smi-tagged)
4584 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
4585 __ cmp(ebx, ecx);
4586 __ j(less_equal, &try_allocate, Label::kNear);
4587 __ mov(ebx, ecx);
4588
4589 // Save mapped parameter count and function.
4590 __ bind(&try_allocate);
4591 __ push(edi);
4592 __ push(ebx);
4593
4594 // Compute the sizes of backing store, parameter map, and arguments object.
4595 // 1. Parameter map, has 2 extra words containing context and backing store.
4596 const int kParameterMapHeaderSize =
4597 FixedArray::kHeaderSize + 2 * kPointerSize;
4598 Label no_parameter_map;
4599 __ test(ebx, ebx);
4600 __ j(zero, &no_parameter_map, Label::kNear);
4601 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
4602 __ bind(&no_parameter_map);
4603
4604 // 2. Backing store.
4605 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
4606
4607 // 3. Arguments object.
4608 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize));
4609
4610 // Do the allocation of all three objects in one go.
4611 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
4612
4613 // eax = address of new object(s) (tagged)
4614 // ecx = argument count (smi-tagged)
4615 // esp[0] = mapped parameter count (tagged)
4616 // esp[4] = function
4617 // esp[8] = parameter count (tagged)
4618 // Get the arguments map from the current native context into edi.
4619 Label has_mapped_parameters, instantiate;
4620 __ mov(edi, NativeContextOperand());
4621 __ mov(ebx, Operand(esp, 0 * kPointerSize));
4622 __ test(ebx, ebx);
4623 __ j(not_zero, &has_mapped_parameters, Label::kNear);
4624 __ mov(
4625 edi,
4626 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
4627 __ jmp(&instantiate, Label::kNear);
4628
4629 __ bind(&has_mapped_parameters);
4630 __ mov(edi, Operand(edi, Context::SlotOffset(
4631 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
4632 __ bind(&instantiate);
4633
4634 // eax = address of new object (tagged)
4635 // ebx = mapped parameter count (tagged)
4636 // ecx = argument count (smi-tagged)
4637 // edi = address of arguments map (tagged)
4638 // esp[0] = mapped parameter count (tagged)
4639 // esp[4] = function
4640 // esp[8] = parameter count (tagged)
4641 // Copy the JS object part.
4642 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
4643 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
4644 masm->isolate()->factory()->empty_fixed_array());
4645 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
4646 masm->isolate()->factory()->empty_fixed_array());
4647
4648 // Set up the callee in-object property.
4649 STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1);
4650 __ mov(edi, Operand(esp, 1 * kPointerSize));
4651 __ AssertNotSmi(edi);
4652 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi);
4653
4654 // Use the length (smi tagged) and set that as an in-object property too.
4655 __ AssertSmi(ecx);
4656 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx);
4657
4658 // Set up the elements pointer in the allocated arguments object.
4659 // If we allocated a parameter map, edi will point there, otherwise to the
4660 // backing store.
4661 __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize));
4662 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
4663
4664 // eax = address of new object (tagged)
4665 // ebx = mapped parameter count (tagged)
4666 // ecx = argument count (tagged)
4667 // edx = address of receiver argument
4668 // edi = address of parameter map or backing store (tagged)
4669 // esp[0] = mapped parameter count (tagged)
4670 // esp[4] = function
4671 // esp[8] = parameter count (tagged)
4672 // Free two registers.
4673 __ push(edx);
4674 __ push(eax);
4675
4676 // Initialize parameter map. If there are no mapped arguments, we're done.
4677 Label skip_parameter_map;
4678 __ test(ebx, ebx);
4679 __ j(zero, &skip_parameter_map);
4680
4681 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
4682 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
4683 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
4684 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
4685 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
4686 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
4687 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
4688
4689 // Copy the parameter slots and the holes in the arguments.
4690 // We need to fill in mapped_parameter_count slots. They index the context,
4691 // where parameters are stored in reverse order, at
4692 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
4693 // The mapped parameter thus need to get indices
4694 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
4695 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
4696 // We loop from right to left.
4697 Label parameters_loop, parameters_test;
4698 __ push(ecx);
4699 __ mov(eax, Operand(esp, 3 * kPointerSize));
4700 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
4701 __ add(ebx, Operand(esp, 5 * kPointerSize));
4702 __ sub(ebx, eax);
4703 __ mov(ecx, isolate()->factory()->the_hole_value());
4704 __ mov(edx, edi);
4705 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
4706 // eax = loop variable (tagged)
4707 // ebx = mapping index (tagged)
4708 // ecx = the hole value
4709 // edx = address of parameter map (tagged)
4710 // edi = address of backing store (tagged)
4711 // esp[0] = argument count (tagged)
4712 // esp[4] = address of new object (tagged)
4713 // esp[8] = address of receiver argument
4714 // esp[12] = mapped parameter count (tagged)
4715 // esp[16] = function
4716 // esp[20] = parameter count (tagged)
4717 __ jmp(&parameters_test, Label::kNear);
4718
4719 __ bind(&parameters_loop);
4720 __ sub(eax, Immediate(Smi::FromInt(1)));
4721 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
4722 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
4723 __ add(ebx, Immediate(Smi::FromInt(1)));
4724 __ bind(&parameters_test);
4725 __ test(eax, eax);
4726 __ j(not_zero, &parameters_loop, Label::kNear);
4727 __ pop(ecx);
4728
4729 __ bind(&skip_parameter_map);
4730
4731 // ecx = argument count (tagged)
4732 // edi = address of backing store (tagged)
4733 // esp[0] = address of new object (tagged)
4734 // esp[4] = address of receiver argument
4735 // esp[8] = mapped parameter count (tagged)
4736 // esp[12] = function
4737 // esp[16] = parameter count (tagged)
4738 // Copy arguments header and remaining slots (if there are any).
4739 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
4740 Immediate(isolate()->factory()->fixed_array_map()));
4741 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
4742
4743 Label arguments_loop, arguments_test;
4744 __ mov(ebx, Operand(esp, 2 * kPointerSize));
4745 __ mov(edx, Operand(esp, 1 * kPointerSize));
4746 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
4747 __ sub(edx, ebx);
4748 __ jmp(&arguments_test, Label::kNear);
4749
4750 __ bind(&arguments_loop);
4751 __ sub(edx, Immediate(kPointerSize));
4752 __ mov(eax, Operand(edx, 0));
4753 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
4754 __ add(ebx, Immediate(Smi::FromInt(1)));
4755
4756 __ bind(&arguments_test);
4757 __ cmp(ebx, ecx);
4758 __ j(less, &arguments_loop, Label::kNear);
4759
4760 // Restore.
4761 __ pop(eax); // Address of arguments object.
4762 __ Drop(4);
4763
4764 // Return.
4765 __ ret(0);
4766
4767 // Do the runtime call to allocate the arguments object.
4768 __ bind(&runtime);
4769 __ pop(eax); // Remove saved mapped parameter count.
4770 __ pop(edi); // Pop saved function.
4771 __ pop(eax); // Remove saved parameter count.
4772 __ pop(eax); // Pop return address.
4773 __ push(edi); // Push function.
4774 __ push(edx); // Push parameters pointer.
4775 __ push(ecx); // Push parameter count.
4776 __ push(eax); // Push return address.
4777 __ TailCallRuntime(Runtime::kNewSloppyArguments);
4778 }
4779
4821 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { 4780 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
4822 // ----------- S t a t e ------------- 4781 // ----------- S t a t e -------------
4823 // -- edi : function 4782 // -- edi : function
4824 // -- esi : context 4783 // -- esi : context
4825 // -- ebp : frame pointer 4784 // -- ebp : frame pointer
4826 // -- esp[0] : return address 4785 // -- esp[0] : return address
4827 // ----------------------------------- 4786 // -----------------------------------
4828 __ AssertFunction(edi); 4787 __ AssertFunction(edi);
4829 4788
4830 // For Ignition we need to skip all possible handler/stub frames until 4789 // For Ignition we need to skip all possible handler/stub frames until
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
5481 return_value_operand, NULL); 5440 return_value_operand, NULL);
5482 } 5441 }
5483 5442
5484 5443
5485 #undef __ 5444 #undef __
5486 5445
5487 } // namespace internal 5446 } // namespace internal
5488 } // namespace v8 5447 } // namespace v8
5489 5448
5490 #endif // V8_TARGET_ARCH_X87 5449 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698