OLD | NEW |
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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 StubRuntimeCallHelper call_helper; | 407 StubRuntimeCallHelper call_helper; |
408 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); | 408 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); |
409 | 409 |
410 __ bind(&miss); | 410 __ bind(&miss); |
411 PropertyAccessCompiler::TailCallBuiltin( | 411 PropertyAccessCompiler::TailCallBuiltin( |
412 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 412 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
413 } | 413 } |
414 | 414 |
415 | 415 |
416 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { | 416 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
417 CHECK(!has_new_target()); | |
418 // The key is in edx and the parameter count is in eax. | 417 // The key is in edx and the parameter count is in eax. |
419 DCHECK(edx.is(ArgumentsAccessReadDescriptor::index())); | 418 DCHECK(edx.is(ArgumentsAccessReadDescriptor::index())); |
420 DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count())); | 419 DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count())); |
421 | 420 |
422 // The displacement is used for skipping the frame pointer on the | 421 // The displacement is used for skipping the frame pointer on the |
423 // stack. It is the offset of the last parameter (if any) relative | 422 // stack. It is the offset of the last parameter (if any) relative |
424 // to the frame pointer. | 423 // to the frame pointer. |
425 static const int kDisplacement = 1 * kPointerSize; | 424 static const int kDisplacement = 1 * kPointerSize; |
426 | 425 |
427 // Check that the key is a smi. | 426 // Check that the key is a smi. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); | 473 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); |
475 } | 474 } |
476 | 475 |
477 | 476 |
478 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 477 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
479 // esp[0] : return address | 478 // esp[0] : return address |
480 // esp[4] : number of parameters | 479 // esp[4] : number of parameters |
481 // esp[8] : receiver displacement | 480 // esp[8] : receiver displacement |
482 // esp[12] : function | 481 // esp[12] : function |
483 | 482 |
484 CHECK(!has_new_target()); | |
485 | |
486 // Check if the calling frame is an arguments adaptor frame. | 483 // Check if the calling frame is an arguments adaptor frame. |
487 Label runtime; | 484 Label runtime; |
488 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 485 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
489 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 486 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
490 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 487 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
491 __ j(not_equal, &runtime, Label::kNear); | 488 __ j(not_equal, &runtime, Label::kNear); |
492 | 489 |
493 // Patch the arguments.length and the parameters pointer. | 490 // Patch the arguments.length and the parameters pointer. |
494 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 491 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
495 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 492 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
496 __ lea(edx, Operand(edx, ecx, times_2, | 493 __ lea(edx, Operand(edx, ecx, times_2, |
497 StandardFrameConstants::kCallerSPOffset)); | 494 StandardFrameConstants::kCallerSPOffset)); |
498 __ mov(Operand(esp, 2 * kPointerSize), edx); | 495 __ mov(Operand(esp, 2 * kPointerSize), edx); |
499 | 496 |
500 __ bind(&runtime); | 497 __ bind(&runtime); |
501 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 498 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
502 } | 499 } |
503 | 500 |
504 | 501 |
505 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 502 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
506 // esp[0] : return address | 503 // esp[0] : return address |
507 // esp[4] : number of parameters (tagged) | 504 // esp[4] : number of parameters (tagged) |
508 // esp[8] : receiver displacement | 505 // esp[8] : receiver displacement |
509 // esp[12] : function | 506 // esp[12] : function |
510 | 507 |
511 // ebx = parameter count (tagged) | 508 // ebx = parameter count (tagged) |
512 __ mov(ebx, Operand(esp, 1 * kPointerSize)); | 509 __ mov(ebx, Operand(esp, 1 * kPointerSize)); |
513 | 510 |
514 CHECK(!has_new_target()); | |
515 | |
516 // Check if the calling frame is an arguments adaptor frame. | 511 // Check if the calling frame is an arguments adaptor frame. |
517 // TODO(rossberg): Factor out some of the bits that are shared with the other | 512 // TODO(rossberg): Factor out some of the bits that are shared with the other |
518 // Generate* functions. | 513 // Generate* functions. |
519 Label runtime; | 514 Label runtime; |
520 Label adaptor_frame, try_allocate; | 515 Label adaptor_frame, try_allocate; |
521 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 516 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
522 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 517 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
523 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 518 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
524 __ j(equal, &adaptor_frame, Label::kNear); | 519 __ j(equal, &adaptor_frame, Label::kNear); |
525 | 520 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 __ j(equal, &adaptor_frame, Label::kNear); | 741 __ j(equal, &adaptor_frame, Label::kNear); |
747 | 742 |
748 // Get the length from the frame. | 743 // Get the length from the frame. |
749 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 744 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
750 __ jmp(&try_allocate, Label::kNear); | 745 __ jmp(&try_allocate, Label::kNear); |
751 | 746 |
752 // Patch the arguments.length and the parameters pointer. | 747 // Patch the arguments.length and the parameters pointer. |
753 __ bind(&adaptor_frame); | 748 __ bind(&adaptor_frame); |
754 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 749 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
755 | 750 |
756 if (has_new_target()) { | |
757 // If the constructor was [[Call]]ed, the call will not push a new.target | |
758 // onto the stack. In that case the arguments array we construct is bogus, | |
759 // bu we do not care as the constructor throws immediately. | |
760 __ cmp(ecx, Immediate(Smi::FromInt(0))); | |
761 Label skip_decrement; | |
762 __ j(equal, &skip_decrement); | |
763 // Subtract 1 from smi-tagged arguments count. | |
764 __ sub(ecx, Immediate(2)); | |
765 __ bind(&skip_decrement); | |
766 } | |
767 | |
768 __ lea(edx, Operand(edx, ecx, times_2, | 751 __ lea(edx, Operand(edx, ecx, times_2, |
769 StandardFrameConstants::kCallerSPOffset)); | 752 StandardFrameConstants::kCallerSPOffset)); |
770 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 753 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
771 __ mov(Operand(esp, 2 * kPointerSize), edx); | 754 __ mov(Operand(esp, 2 * kPointerSize), edx); |
772 | 755 |
773 // Try the new space allocation. Start out with computing the size of | 756 // Try the new space allocation. Start out with computing the size of |
774 // the arguments object and the elements array. | 757 // the arguments object and the elements array. |
775 Label add_arguments_object; | 758 Label add_arguments_object; |
776 __ bind(&try_allocate); | 759 __ bind(&try_allocate); |
777 __ test(ecx, ecx); | 760 __ test(ecx, ecx); |
(...skipping 4360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5138 Operand(ebp, 7 * kPointerSize), NULL); | 5121 Operand(ebp, 7 * kPointerSize), NULL); |
5139 } | 5122 } |
5140 | 5123 |
5141 | 5124 |
5142 #undef __ | 5125 #undef __ |
5143 | 5126 |
5144 } // namespace internal | 5127 } // namespace internal |
5145 } // namespace v8 | 5128 } // namespace v8 |
5146 | 5129 |
5147 #endif // V8_TARGET_ARCH_X87 | 5130 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |