| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 __ CallRuntime(Runtime::kNewObject, 2); | 281 __ CallRuntime(Runtime::kNewObject, 2); |
| 282 __ Pop(x2); | 282 __ Pop(x2); |
| 283 } | 283 } |
| 284 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); | 284 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); |
| 285 __ Ret(); | 285 __ Ret(); |
| 286 } | 286 } |
| 287 | 287 |
| 288 | 288 |
| 289 static void CallRuntimePassFunction(MacroAssembler* masm, | 289 static void CallRuntimePassFunction(MacroAssembler* masm, |
| 290 Runtime::FunctionId function_id) { | 290 Runtime::FunctionId function_id) { |
| 291 // ----------- S t a t e ------------- |
| 292 // -- x1 : target function (preserved for callee) |
| 293 // -- x3 : new target (preserved for callee) |
| 294 // ----------------------------------- |
| 295 |
| 291 FrameScope scope(masm, StackFrame::INTERNAL); | 296 FrameScope scope(masm, StackFrame::INTERNAL); |
| 292 // - Push a copy of the function onto the stack. | 297 // Push a copy of the target function and the new target. |
| 293 // - Push another copy as a parameter to the runtime call. | 298 // Push another copy as a parameter to the runtime call. |
| 294 __ Push(x1, x1); | 299 __ Push(x1, x3, x1); |
| 295 | 300 |
| 296 __ CallRuntime(function_id, 1); | 301 __ CallRuntime(function_id, 1); |
| 297 | 302 |
| 298 // - Restore receiver. | 303 // Restore target function and new target. |
| 299 __ Pop(x1); | 304 __ Pop(x3, x1); |
| 300 } | 305 } |
| 301 | 306 |
| 302 | 307 |
| 303 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 308 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 304 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | 309 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 305 __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset)); | 310 __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset)); |
| 306 __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag); | 311 __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag); |
| 307 __ Br(x2); | 312 __ Br(x2); |
| 308 } | 313 } |
| 309 | 314 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 } | 546 } |
| 542 | 547 |
| 543 // Set up pointer to last argument. | 548 // Set up pointer to last argument. |
| 544 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); | 549 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); |
| 545 | 550 |
| 546 // Copy arguments and receiver to the expression stack. | 551 // Copy arguments and receiver to the expression stack. |
| 547 // Copy 2 values every loop to use ldp/stp. | 552 // Copy 2 values every loop to use ldp/stp. |
| 548 // x0: number of arguments | 553 // x0: number of arguments |
| 549 // x1: constructor function | 554 // x1: constructor function |
| 550 // x2: address of last argument (caller sp) | 555 // x2: address of last argument (caller sp) |
| 556 // x3: new target |
| 551 // jssp[0]: receiver | 557 // jssp[0]: receiver |
| 552 // jssp[1]: receiver | 558 // jssp[1]: receiver |
| 553 // jssp[2]: new.target | 559 // jssp[2]: new.target |
| 554 // jssp[3]: number of arguments (smi-tagged) | 560 // jssp[3]: number of arguments (smi-tagged) |
| 555 // Compute the start address of the copy in x3. | 561 // Compute the start address of the copy in x3. |
| 556 __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2)); | 562 __ Add(x4, x2, Operand(argc, LSL, kPointerSizeLog2)); |
| 557 Label loop, entry, done_copying_arguments; | 563 Label loop, entry, done_copying_arguments; |
| 558 __ B(&entry); | 564 __ B(&entry); |
| 559 __ Bind(&loop); | 565 __ Bind(&loop); |
| 560 __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex)); | 566 __ Ldp(x10, x11, MemOperand(x4, -2 * kPointerSize, PreIndex)); |
| 561 __ Push(x11, x10); | 567 __ Push(x11, x10); |
| 562 __ Bind(&entry); | 568 __ Bind(&entry); |
| 563 __ Cmp(x3, x2); | 569 __ Cmp(x4, x2); |
| 564 __ B(gt, &loop); | 570 __ B(gt, &loop); |
| 565 // Because we copied values 2 by 2 we may have copied one extra value. | 571 // Because we copied values 2 by 2 we may have copied one extra value. |
| 566 // Drop it if that is the case. | 572 // Drop it if that is the case. |
| 567 __ B(eq, &done_copying_arguments); | 573 __ B(eq, &done_copying_arguments); |
| 568 __ Drop(1); | 574 __ Drop(1); |
| 569 __ Bind(&done_copying_arguments); | 575 __ Bind(&done_copying_arguments); |
| 570 | 576 |
| 571 // Call the function. | 577 // Call the function. |
| 572 // x0: number of arguments | 578 // x0: number of arguments |
| 573 // x1: constructor function | 579 // x1: constructor function |
| 580 // x3: new target |
| 574 if (is_api_function) { | 581 if (is_api_function) { |
| 575 __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset)); | 582 __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset)); |
| 576 Handle<Code> code = | 583 Handle<Code> code = |
| 577 masm->isolate()->builtins()->HandleApiCallConstruct(); | 584 masm->isolate()->builtins()->HandleApiCallConstruct(); |
| 578 __ Call(code, RelocInfo::CODE_TARGET); | 585 __ Call(code, RelocInfo::CODE_TARGET); |
| 579 } else { | 586 } else { |
| 580 ParameterCount actual(argc); | 587 ParameterCount actual(argc); |
| 581 __ InvokeFunction(constructor, actual, CALL_FUNCTION, NullCallWrapper()); | 588 __ InvokeFunction(constructor, new_target, actual, CALL_FUNCTION, |
| 589 NullCallWrapper()); |
| 582 } | 590 } |
| 583 | 591 |
| 584 // Store offset of return address for deoptimizer. | 592 // Store offset of return address for deoptimizer. |
| 585 if (create_implicit_receiver && !is_api_function) { | 593 if (create_implicit_receiver && !is_api_function) { |
| 586 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 594 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
| 587 } | 595 } |
| 588 | 596 |
| 589 // Restore the context from the frame. | 597 // Restore the context from the frame. |
| 590 // x0: result | 598 // x0: result |
| 591 // jssp[0]: receiver | 599 // jssp[0]: receiver |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 // For now, we are relying on the fact that make_code_young doesn't do any | 947 // For now, we are relying on the fact that make_code_young doesn't do any |
| 940 // garbage collection which allows us to save/restore the registers without | 948 // garbage collection which allows us to save/restore the registers without |
| 941 // worrying about which of them contain pointers. We also don't build an | 949 // worrying about which of them contain pointers. We also don't build an |
| 942 // internal frame to make the code fast, since we shouldn't have to do stack | 950 // internal frame to make the code fast, since we shouldn't have to do stack |
| 943 // crawls in MakeCodeYoung. This seems a bit fragile. | 951 // crawls in MakeCodeYoung. This seems a bit fragile. |
| 944 | 952 |
| 945 // The following caller-saved registers must be saved and restored when | 953 // The following caller-saved registers must be saved and restored when |
| 946 // calling through to the runtime: | 954 // calling through to the runtime: |
| 947 // x0 - The address from which to resume execution. | 955 // x0 - The address from which to resume execution. |
| 948 // x1 - isolate | 956 // x1 - isolate |
| 957 // x3 - new target |
| 949 // lr - The return address for the JSFunction itself. It has not yet been | 958 // lr - The return address for the JSFunction itself. It has not yet been |
| 950 // preserved on the stack because the frame setup code was replaced | 959 // preserved on the stack because the frame setup code was replaced |
| 951 // with a call to this stub, to handle code ageing. | 960 // with a call to this stub, to handle code ageing. |
| 952 { | 961 { |
| 953 FrameScope scope(masm, StackFrame::MANUAL); | 962 FrameScope scope(masm, StackFrame::MANUAL); |
| 954 __ Push(x0, x1, fp, lr); | 963 __ Push(x0, x1, x3, fp, lr); |
| 955 __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); | 964 __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); |
| 956 __ CallCFunction( | 965 __ CallCFunction( |
| 957 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 966 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
| 958 __ Pop(lr, fp, x1, x0); | 967 __ Pop(lr, fp, x3, x1, x0); |
| 959 } | 968 } |
| 960 | 969 |
| 961 // The calling function has been made young again, so return to execute the | 970 // The calling function has been made young again, so return to execute the |
| 962 // real frame set-up code. | 971 // real frame set-up code. |
| 963 __ Br(x0); | 972 __ Br(x0); |
| 964 } | 973 } |
| 965 | 974 |
| 966 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ | 975 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ |
| 967 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ | 976 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ |
| 968 MacroAssembler* masm) { \ | 977 MacroAssembler* masm) { \ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 979 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 988 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
| 980 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 989 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
| 981 // that make_code_young doesn't do any garbage collection which allows us to | 990 // that make_code_young doesn't do any garbage collection which allows us to |
| 982 // save/restore the registers without worrying about which of them contain | 991 // save/restore the registers without worrying about which of them contain |
| 983 // pointers. | 992 // pointers. |
| 984 | 993 |
| 985 // The following caller-saved registers must be saved and restored when | 994 // The following caller-saved registers must be saved and restored when |
| 986 // calling through to the runtime: | 995 // calling through to the runtime: |
| 987 // x0 - The address from which to resume execution. | 996 // x0 - The address from which to resume execution. |
| 988 // x1 - isolate | 997 // x1 - isolate |
| 998 // x3 - new target |
| 989 // lr - The return address for the JSFunction itself. It has not yet been | 999 // lr - The return address for the JSFunction itself. It has not yet been |
| 990 // preserved on the stack because the frame setup code was replaced | 1000 // preserved on the stack because the frame setup code was replaced |
| 991 // with a call to this stub, to handle code ageing. | 1001 // with a call to this stub, to handle code ageing. |
| 992 { | 1002 { |
| 993 FrameScope scope(masm, StackFrame::MANUAL); | 1003 FrameScope scope(masm, StackFrame::MANUAL); |
| 994 __ Push(x0, x1, fp, lr); | 1004 __ Push(x0, x1, x3, fp, lr); |
| 995 __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); | 1005 __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); |
| 996 __ CallCFunction( | 1006 __ CallCFunction( |
| 997 ExternalReference::get_mark_code_as_executed_function( | 1007 ExternalReference::get_mark_code_as_executed_function( |
| 998 masm->isolate()), 2); | 1008 masm->isolate()), 2); |
| 999 __ Pop(lr, fp, x1, x0); | 1009 __ Pop(lr, fp, x3, x1, x0); |
| 1000 | 1010 |
| 1001 // Perform prologue operations usually performed by the young code stub. | 1011 // Perform prologue operations usually performed by the young code stub. |
| 1002 __ EmitFrameSetupForCodeAgePatching(masm); | 1012 __ EmitFrameSetupForCodeAgePatching(masm); |
| 1003 } | 1013 } |
| 1004 | 1014 |
| 1005 // Jump to point after the code-age stub. | 1015 // Jump to point after the code-age stub. |
| 1006 __ Add(x0, x0, kNoCodeAgeSequenceLength); | 1016 __ Add(x0, x0, kNoCodeAgeSequenceLength); |
| 1007 __ Br(x0); | 1017 __ Br(x0); |
| 1008 } | 1018 } |
| 1009 | 1019 |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 | 1544 |
| 1535 // ----------- S t a t e ------------- | 1545 // ----------- S t a t e ------------- |
| 1536 // -- x0 : the number of arguments (not including the receiver) | 1546 // -- x0 : the number of arguments (not including the receiver) |
| 1537 // -- x1 : the function to call (checked to be a JSFunction) | 1547 // -- x1 : the function to call (checked to be a JSFunction) |
| 1538 // -- x2 : the shared function info. | 1548 // -- x2 : the shared function info. |
| 1539 // -- cp : the function context. | 1549 // -- cp : the function context. |
| 1540 // ----------------------------------- | 1550 // ----------------------------------- |
| 1541 | 1551 |
| 1542 __ Ldrsw( | 1552 __ Ldrsw( |
| 1543 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); | 1553 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1544 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); | 1554 __ Ldr(x4, FieldMemOperand(x1, JSFunction::kCodeEntryOffset)); |
| 1545 ParameterCount actual(x0); | 1555 ParameterCount actual(x0); |
| 1546 ParameterCount expected(x2); | 1556 ParameterCount expected(x2); |
| 1547 __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1557 __ InvokeCode(x4, no_reg, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1548 | 1558 |
| 1549 // The function is a "classConstructor", need to raise an exception. | 1559 // The function is a "classConstructor", need to raise an exception. |
| 1550 __ bind(&class_constructor); | 1560 __ bind(&class_constructor); |
| 1551 { | 1561 { |
| 1552 FrameScope frame(masm, StackFrame::INTERNAL); | 1562 FrameScope frame(masm, StackFrame::INTERNAL); |
| 1553 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | 1563 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
| 1554 } | 1564 } |
| 1555 } | 1565 } |
| 1556 | 1566 |
| 1557 | 1567 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 } | 1934 } |
| 1925 } | 1935 } |
| 1926 | 1936 |
| 1927 | 1937 |
| 1928 #undef __ | 1938 #undef __ |
| 1929 | 1939 |
| 1930 } // namespace internal | 1940 } // namespace internal |
| 1931 } // namespace v8 | 1941 } // namespace v8 |
| 1932 | 1942 |
| 1933 #endif // V8_TARGET_ARCH_ARM | 1943 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |