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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 | 524 |
525 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 525 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
526 bool is_api_function, | 526 bool is_api_function, |
527 bool create_implicit_receiver, | 527 bool create_implicit_receiver, |
528 bool check_derived_construct) { | 528 bool check_derived_construct) { |
529 // ----------- S t a t e ------------- | 529 // ----------- S t a t e ------------- |
530 // -- r0 : number of arguments | 530 // -- r0 : number of arguments |
531 // -- r1 : constructor function | 531 // -- r1 : constructor function |
532 // -- r2 : allocation site or undefined | 532 // -- r2 : allocation site or undefined |
533 // -- r3 : new target | 533 // -- r3 : new target |
| 534 // -- cp : context |
534 // -- lr : return address | 535 // -- lr : return address |
535 // -- sp[...]: constructor arguments | 536 // -- sp[...]: constructor arguments |
536 // ----------------------------------- | 537 // ----------------------------------- |
537 | 538 |
538 Isolate* isolate = masm->isolate(); | 539 Isolate* isolate = masm->isolate(); |
539 | 540 |
540 // Enter a construct frame. | 541 // Enter a construct frame. |
541 { | 542 { |
542 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); | 543 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); |
543 | 544 |
544 // Preserve the incoming parameters on the stack. | 545 // Preserve the incoming parameters on the stack. |
545 __ AssertUndefinedOrAllocationSite(r2, r4); | 546 __ AssertUndefinedOrAllocationSite(r2, r4); |
| 547 __ Push(cp); |
546 __ SmiTag(r0); | 548 __ SmiTag(r0); |
547 __ Push(r2, r0); | 549 __ Push(r2, r0); |
548 | 550 |
549 if (create_implicit_receiver) { | 551 if (create_implicit_receiver) { |
550 // Allocate the new receiver object. | 552 // Allocate the new receiver object. |
551 __ Push(r1, r3); | 553 __ Push(r1, r3); |
552 FastNewObjectStub stub(masm->isolate()); | 554 FastNewObjectStub stub(masm->isolate()); |
553 __ CallStub(&stub); | 555 __ CallStub(&stub); |
554 __ mov(r4, r0); | 556 __ mov(r4, r0); |
555 __ Pop(r1, r3); | 557 __ Pop(r1, r3); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 | 617 |
616 // Store offset of return address for deoptimizer. | 618 // Store offset of return address for deoptimizer. |
617 if (create_implicit_receiver && !is_api_function) { | 619 if (create_implicit_receiver && !is_api_function) { |
618 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 620 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
619 } | 621 } |
620 | 622 |
621 // Restore context from the frame. | 623 // Restore context from the frame. |
622 // r0: result | 624 // r0: result |
623 // sp[0]: receiver | 625 // sp[0]: receiver |
624 // sp[1]: number of arguments (smi-tagged) | 626 // sp[1]: number of arguments (smi-tagged) |
625 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 627 __ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset)); |
626 | 628 |
627 if (create_implicit_receiver) { | 629 if (create_implicit_receiver) { |
628 // If the result is an object (in the ECMA sense), we should get rid | 630 // If the result is an object (in the ECMA sense), we should get rid |
629 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 631 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
630 // on page 74. | 632 // on page 74. |
631 Label use_receiver, exit; | 633 Label use_receiver, exit; |
632 | 634 |
633 // If the result is a smi, it is *not* an object in the ECMA sense. | 635 // If the result is a smi, it is *not* an object in the ECMA sense. |
634 // r0: result | 636 // r0: result |
635 // sp[0]: receiver | 637 // sp[0]: receiver |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 bool is_construct) { | 746 bool is_construct) { |
745 // Called from Generate_JS_Entry | 747 // Called from Generate_JS_Entry |
746 // r0: new.target | 748 // r0: new.target |
747 // r1: function | 749 // r1: function |
748 // r2: receiver | 750 // r2: receiver |
749 // r3: argc | 751 // r3: argc |
750 // r4: argv | 752 // r4: argv |
751 // r5-r6, r8 (if !FLAG_enable_embedded_constant_pool) and cp may be clobbered | 753 // r5-r6, r8 (if !FLAG_enable_embedded_constant_pool) and cp may be clobbered |
752 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 754 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
753 | 755 |
754 // Clear the context before we push it when entering the internal frame. | |
755 __ mov(cp, Operand::Zero()); | |
756 | |
757 // Enter an internal frame. | 756 // Enter an internal frame. |
758 { | 757 { |
759 FrameScope scope(masm, StackFrame::INTERNAL); | 758 FrameScope scope(masm, StackFrame::INTERNAL); |
760 | 759 |
761 // Setup the context (we need to use the caller context from the isolate). | 760 // Setup the context (we need to use the caller context from the isolate). |
762 ExternalReference context_address(Isolate::kContextAddress, | 761 ExternalReference context_address(Isolate::kContextAddress, |
763 masm->isolate()); | 762 masm->isolate()); |
764 __ mov(cp, Operand(context_address)); | 763 __ mov(cp, Operand(context_address)); |
765 __ ldr(cp, MemOperand(cp)); | 764 __ ldr(cp, MemOperand(cp)); |
766 | 765 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 // o sp: stack pointer | 847 // o sp: stack pointer |
849 // o lr: return address | 848 // o lr: return address |
850 // | 849 // |
851 // The function builds an interpreter frame. See InterpreterFrameConstants in | 850 // The function builds an interpreter frame. See InterpreterFrameConstants in |
852 // frames.h for its layout. | 851 // frames.h for its layout. |
853 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { | 852 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
854 // Open a frame scope to indicate that there is a frame on the stack. The | 853 // Open a frame scope to indicate that there is a frame on the stack. The |
855 // MANUAL indicates that the scope shouldn't actually generate code to set up | 854 // MANUAL indicates that the scope shouldn't actually generate code to set up |
856 // the frame (that is done below). | 855 // the frame (that is done below). |
857 FrameScope frame_scope(masm, StackFrame::MANUAL); | 856 FrameScope frame_scope(masm, StackFrame::MANUAL); |
858 __ PushFixedFrame(r1); | 857 __ PushStandardFrame(r1); |
859 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
860 | 858 |
861 // Get the bytecode array from the function object and load the pointer to the | 859 // Get the bytecode array from the function object and load the pointer to the |
862 // first entry into kInterpreterBytecodeRegister. | 860 // first entry into kInterpreterBytecodeRegister. |
863 __ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 861 __ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
864 Register debug_info = kInterpreterBytecodeArrayRegister; | 862 Register debug_info = kInterpreterBytecodeArrayRegister; |
865 DCHECK(!debug_info.is(r0)); | 863 DCHECK(!debug_info.is(r0)); |
866 __ ldr(debug_info, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset)); | 864 __ ldr(debug_info, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset)); |
867 __ cmp(debug_info, Operand(DebugInfo::uninitialized())); | 865 __ cmp(debug_info, Operand(DebugInfo::uninitialized())); |
868 // Load original bytecode array or the debug copy. | 866 // Load original bytecode array or the debug copy. |
869 __ ldr(kInterpreterBytecodeArrayRegister, | 867 __ ldr(kInterpreterBytecodeArrayRegister, |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 // r3 - new target | 1183 // r3 - new target |
1186 FrameScope scope(masm, StackFrame::MANUAL); | 1184 FrameScope scope(masm, StackFrame::MANUAL); |
1187 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); | 1185 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); |
1188 __ PrepareCallCFunction(2, 0, r2); | 1186 __ PrepareCallCFunction(2, 0, r2); |
1189 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); | 1187 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
1190 __ CallCFunction(ExternalReference::get_mark_code_as_executed_function( | 1188 __ CallCFunction(ExternalReference::get_mark_code_as_executed_function( |
1191 masm->isolate()), 2); | 1189 masm->isolate()), 2); |
1192 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); | 1190 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); |
1193 | 1191 |
1194 // Perform prologue operations usually performed by the young code stub. | 1192 // Perform prologue operations usually performed by the young code stub. |
1195 __ PushFixedFrame(r1); | 1193 __ PushStandardFrame(r1); |
1196 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
1197 | 1194 |
1198 // Jump to point after the code-age stub. | 1195 // Jump to point after the code-age stub. |
1199 __ add(r0, r0, Operand(kNoCodeAgeSequenceLength)); | 1196 __ add(r0, r0, Operand(kNoCodeAgeSequenceLength)); |
1200 __ mov(pc, r0); | 1197 __ mov(pc, r0); |
1201 } | 1198 } |
1202 | 1199 |
1203 | 1200 |
1204 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 1201 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
1205 GenerateMakeCodeYoungAgainCommon(masm); | 1202 GenerateMakeCodeYoungAgainCommon(masm); |
1206 } | 1203 } |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 ExternalReference debug_is_active = | 1935 ExternalReference debug_is_active = |
1939 ExternalReference::debug_is_active_address(masm->isolate()); | 1936 ExternalReference::debug_is_active_address(masm->isolate()); |
1940 __ mov(scratch1, Operand(debug_is_active)); | 1937 __ mov(scratch1, Operand(debug_is_active)); |
1941 __ ldrb(scratch1, MemOperand(scratch1)); | 1938 __ ldrb(scratch1, MemOperand(scratch1)); |
1942 __ cmp(scratch1, Operand(0)); | 1939 __ cmp(scratch1, Operand(0)); |
1943 __ b(ne, &done); | 1940 __ b(ne, &done); |
1944 | 1941 |
1945 // Drop possible interpreter handler/stub frame. | 1942 // Drop possible interpreter handler/stub frame. |
1946 { | 1943 { |
1947 Label no_interpreter_frame; | 1944 Label no_interpreter_frame; |
1948 __ ldr(scratch3, MemOperand(fp, StandardFrameConstants::kMarkerOffset)); | 1945 __ ldr(scratch3, |
| 1946 MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset)); |
1949 __ cmp(scratch3, Operand(Smi::FromInt(StackFrame::STUB))); | 1947 __ cmp(scratch3, Operand(Smi::FromInt(StackFrame::STUB))); |
1950 __ b(ne, &no_interpreter_frame); | 1948 __ b(ne, &no_interpreter_frame); |
1951 __ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1949 __ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1952 __ bind(&no_interpreter_frame); | 1950 __ bind(&no_interpreter_frame); |
1953 } | 1951 } |
1954 | 1952 |
1955 // Check if next frame is an arguments adaptor frame. | 1953 // Check if next frame is an arguments adaptor frame. |
1956 Label no_arguments_adaptor, formal_parameter_count_loaded; | 1954 Label no_arguments_adaptor, formal_parameter_count_loaded; |
1957 __ ldr(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1955 __ ldr(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1958 __ ldr(scratch3, | 1956 __ ldr(scratch3, |
1959 MemOperand(scratch2, StandardFrameConstants::kContextOffset)); | 1957 MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
1960 __ cmp(scratch3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1958 __ cmp(scratch3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
1961 __ b(ne, &no_arguments_adaptor); | 1959 __ b(ne, &no_arguments_adaptor); |
1962 | 1960 |
1963 // Drop arguments adaptor frame and load arguments count. | 1961 // Drop arguments adaptor frame and load arguments count. |
1964 __ mov(fp, scratch2); | 1962 __ mov(fp, scratch2); |
1965 __ ldr(scratch1, | 1963 __ ldr(scratch1, |
1966 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1964 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1967 __ SmiUntag(scratch1); | 1965 __ SmiUntag(scratch1); |
1968 __ b(&formal_parameter_count_loaded); | 1966 __ b(&formal_parameter_count_loaded); |
1969 | 1967 |
1970 __ bind(&no_arguments_adaptor); | 1968 __ bind(&no_arguments_adaptor); |
1971 // Load caller's formal parameter count | 1969 // Load caller's formal parameter count |
1972 __ ldr(scratch1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1970 __ ldr(scratch1, |
| 1971 MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset)); |
1973 __ ldr(scratch1, | 1972 __ ldr(scratch1, |
1974 FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset)); | 1973 FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset)); |
1975 __ ldr(scratch1, | 1974 __ ldr(scratch1, |
1976 FieldMemOperand(scratch1, | 1975 FieldMemOperand(scratch1, |
1977 SharedFunctionInfo::kFormalParameterCountOffset)); | 1976 SharedFunctionInfo::kFormalParameterCountOffset)); |
1978 __ SmiUntag(scratch1); | 1977 __ SmiUntag(scratch1); |
1979 | 1978 |
1980 __ bind(&formal_parameter_count_loaded); | 1979 __ bind(&formal_parameter_count_loaded); |
1981 | 1980 |
1982 // Calculate the end of destination area where we will put the arguments | 1981 // Calculate the end of destination area where we will put the arguments |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2567 } | 2566 } |
2568 } | 2567 } |
2569 | 2568 |
2570 | 2569 |
2571 #undef __ | 2570 #undef __ |
2572 | 2571 |
2573 } // namespace internal | 2572 } // namespace internal |
2574 } // namespace v8 | 2573 } // namespace v8 |
2575 | 2574 |
2576 #endif // V8_TARGET_ARCH_ARM | 2575 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |