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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 __ CallRuntime(Runtime::kNewObject, 2); | 285 __ CallRuntime(Runtime::kNewObject, 2); |
286 __ Pop(r2); | 286 __ Pop(r2); |
287 } | 287 } |
288 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | 288 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
289 __ Ret(); | 289 __ Ret(); |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 static void CallRuntimePassFunction( | 293 static void CallRuntimePassFunction( |
294 MacroAssembler* masm, Runtime::FunctionId function_id) { | 294 MacroAssembler* masm, Runtime::FunctionId function_id) { |
| 295 // ----------- S t a t e ------------- |
| 296 // -- r1 : target function (preserved for callee) |
| 297 // -- r3 : new target (preserved for callee) |
| 298 // ----------------------------------- |
| 299 |
295 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 300 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
296 // Push a copy of the function onto the stack. | 301 // Push a copy of the target function and the new target. |
297 __ push(r1); | 302 __ push(r1); |
| 303 __ push(r3); |
298 // Push function as parameter to the runtime call. | 304 // Push function as parameter to the runtime call. |
299 __ Push(r1); | 305 __ Push(r1); |
300 | 306 |
301 __ CallRuntime(function_id, 1); | 307 __ CallRuntime(function_id, 1); |
302 // Restore receiver. | 308 // Restore target function and new target. |
| 309 __ pop(r3); |
303 __ pop(r1); | 310 __ pop(r1); |
304 } | 311 } |
305 | 312 |
306 | 313 |
307 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 314 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
308 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 315 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
309 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); | 316 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); |
310 __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag)); | 317 __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag)); |
311 __ Jump(r2); | 318 __ Jump(r2); |
312 } | 319 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 __ PushRoot(Heap::kTheHoleValueRootIndex); | 539 __ PushRoot(Heap::kTheHoleValueRootIndex); |
533 } | 540 } |
534 | 541 |
535 // Set up pointer to last argument. | 542 // Set up pointer to last argument. |
536 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); | 543 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); |
537 | 544 |
538 // Copy arguments and receiver to the expression stack. | 545 // Copy arguments and receiver to the expression stack. |
539 // r0: number of arguments | 546 // r0: number of arguments |
540 // r1: constructor function | 547 // r1: constructor function |
541 // r2: address of last argument (caller sp) | 548 // r2: address of last argument (caller sp) |
542 // r3: number of arguments (smi-tagged) | 549 // r3: new target |
| 550 // r4: number of arguments (smi-tagged) |
543 // sp[0]: receiver | 551 // sp[0]: receiver |
544 // sp[1]: receiver | 552 // sp[1]: receiver |
545 // sp[2]: new.target | 553 // sp[2]: new.target |
546 // sp[3]: number of arguments (smi-tagged) | 554 // sp[3]: number of arguments (smi-tagged) |
547 Label loop, entry; | 555 Label loop, entry; |
548 __ SmiTag(r3, r0); | 556 __ SmiTag(r4, r0); |
549 __ b(&entry); | 557 __ b(&entry); |
550 __ bind(&loop); | 558 __ bind(&loop); |
551 __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1)); | 559 __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2 - 1)); |
552 __ push(ip); | 560 __ push(ip); |
553 __ bind(&entry); | 561 __ bind(&entry); |
554 __ sub(r3, r3, Operand(2), SetCC); | 562 __ sub(r4, r4, Operand(2), SetCC); |
555 __ b(ge, &loop); | 563 __ b(ge, &loop); |
556 | 564 |
557 // Call the function. | 565 // Call the function. |
558 // r0: number of arguments | 566 // r0: number of arguments |
559 // r1: constructor function | 567 // r1: constructor function |
| 568 // r3: new target |
560 if (is_api_function) { | 569 if (is_api_function) { |
561 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 570 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
562 Handle<Code> code = | 571 Handle<Code> code = |
563 masm->isolate()->builtins()->HandleApiCallConstruct(); | 572 masm->isolate()->builtins()->HandleApiCallConstruct(); |
564 __ Call(code, RelocInfo::CODE_TARGET); | 573 __ Call(code, RelocInfo::CODE_TARGET); |
565 } else { | 574 } else { |
566 ParameterCount actual(r0); | 575 ParameterCount actual(r0); |
567 __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper()); | 576 __ InvokeFunction(r1, r3, actual, CALL_FUNCTION, NullCallWrapper()); |
568 } | 577 } |
569 | 578 |
570 // Store offset of return address for deoptimizer. | 579 // Store offset of return address for deoptimizer. |
571 if (create_implicit_receiver && !is_api_function) { | 580 if (create_implicit_receiver && !is_api_function) { |
572 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 581 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
573 } | 582 } |
574 | 583 |
575 // Restore context from the frame. | 584 // Restore context from the frame. |
576 // r0: result | 585 // r0: result |
577 // sp[0]: receiver | 586 // sp[0]: receiver |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 // For now, we are relying on the fact that make_code_young doesn't do any | 988 // For now, we are relying on the fact that make_code_young doesn't do any |
980 // garbage collection which allows us to save/restore the registers without | 989 // garbage collection which allows us to save/restore the registers without |
981 // worrying about which of them contain pointers. We also don't build an | 990 // worrying about which of them contain pointers. We also don't build an |
982 // internal frame to make the code faster, since we shouldn't have to do stack | 991 // internal frame to make the code faster, since we shouldn't have to do stack |
983 // crawls in MakeCodeYoung. This seems a bit fragile. | 992 // crawls in MakeCodeYoung. This seems a bit fragile. |
984 | 993 |
985 // The following registers must be saved and restored when calling through to | 994 // The following registers must be saved and restored when calling through to |
986 // the runtime: | 995 // the runtime: |
987 // r0 - contains return address (beginning of patch sequence) | 996 // r0 - contains return address (beginning of patch sequence) |
988 // r1 - isolate | 997 // r1 - isolate |
| 998 // r3 - new target |
989 FrameScope scope(masm, StackFrame::MANUAL); | 999 FrameScope scope(masm, StackFrame::MANUAL); |
990 __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); | 1000 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); |
991 __ PrepareCallCFunction(2, 0, r2); | 1001 __ PrepareCallCFunction(2, 0, r2); |
992 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); | 1002 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
993 __ CallCFunction( | 1003 __ CallCFunction( |
994 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 1004 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
995 __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); | 1005 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); |
996 __ mov(pc, r0); | 1006 __ mov(pc, r0); |
997 } | 1007 } |
998 | 1008 |
999 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ | 1009 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ |
1000 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ | 1010 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ |
1001 MacroAssembler* masm) { \ | 1011 MacroAssembler* masm) { \ |
1002 GenerateMakeCodeYoungAgainCommon(masm); \ | 1012 GenerateMakeCodeYoungAgainCommon(masm); \ |
1003 } \ | 1013 } \ |
1004 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ | 1014 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ |
1005 MacroAssembler* masm) { \ | 1015 MacroAssembler* masm) { \ |
1006 GenerateMakeCodeYoungAgainCommon(masm); \ | 1016 GenerateMakeCodeYoungAgainCommon(masm); \ |
1007 } | 1017 } |
1008 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) | 1018 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) |
1009 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR | 1019 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR |
1010 | 1020 |
1011 | 1021 |
1012 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 1022 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
1013 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 1023 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
1014 // that make_code_young doesn't do any garbage collection which allows us to | 1024 // that make_code_young doesn't do any garbage collection which allows us to |
1015 // save/restore the registers without worrying about which of them contain | 1025 // save/restore the registers without worrying about which of them contain |
1016 // pointers. | 1026 // pointers. |
1017 | 1027 |
1018 // The following registers must be saved and restored when calling through to | 1028 // The following registers must be saved and restored when calling through to |
1019 // the runtime: | 1029 // the runtime: |
1020 // r0 - contains return address (beginning of patch sequence) | 1030 // r0 - contains return address (beginning of patch sequence) |
1021 // r1 - isolate | 1031 // r1 - isolate |
| 1032 // r3 - new target |
1022 FrameScope scope(masm, StackFrame::MANUAL); | 1033 FrameScope scope(masm, StackFrame::MANUAL); |
1023 __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); | 1034 __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); |
1024 __ PrepareCallCFunction(2, 0, r2); | 1035 __ PrepareCallCFunction(2, 0, r2); |
1025 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); | 1036 __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
1026 __ CallCFunction(ExternalReference::get_mark_code_as_executed_function( | 1037 __ CallCFunction(ExternalReference::get_mark_code_as_executed_function( |
1027 masm->isolate()), 2); | 1038 masm->isolate()), 2); |
1028 __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); | 1039 __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit()); |
1029 | 1040 |
1030 // Perform prologue operations usually performed by the young code stub. | 1041 // Perform prologue operations usually performed by the young code stub. |
1031 __ PushFixedFrame(r1); | 1042 __ PushFixedFrame(r1); |
1032 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 1043 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
1033 | 1044 |
1034 // Jump to point after the code-age stub. | 1045 // Jump to point after the code-age stub. |
1035 __ add(r0, r0, Operand(kNoCodeAgeSequenceLength)); | 1046 __ add(r0, r0, Operand(kNoCodeAgeSequenceLength)); |
1036 __ mov(pc, r0); | 1047 __ mov(pc, r0); |
1037 } | 1048 } |
1038 | 1049 |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 // ----------- S t a t e ------------- | 1552 // ----------- S t a t e ------------- |
1542 // -- r0 : the number of arguments (not including the receiver) | 1553 // -- r0 : the number of arguments (not including the receiver) |
1543 // -- r1 : the function to call (checked to be a JSFunction) | 1554 // -- r1 : the function to call (checked to be a JSFunction) |
1544 // -- r2 : the shared function info. | 1555 // -- r2 : the shared function info. |
1545 // -- cp : the function context. | 1556 // -- cp : the function context. |
1546 // ----------------------------------- | 1557 // ----------------------------------- |
1547 | 1558 |
1548 __ ldr(r2, | 1559 __ ldr(r2, |
1549 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); | 1560 FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset)); |
1550 __ SmiUntag(r2); | 1561 __ SmiUntag(r2); |
1551 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 1562 __ ldr(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
1552 ParameterCount actual(r0); | 1563 ParameterCount actual(r0); |
1553 ParameterCount expected(r2); | 1564 ParameterCount expected(r2); |
1554 __ InvokeCode(r3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1565 __ InvokeCode(r4, no_reg, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
1555 | 1566 |
1556 // The function is a "classConstructor", need to raise an exception. | 1567 // The function is a "classConstructor", need to raise an exception. |
1557 __ bind(&class_constructor); | 1568 __ bind(&class_constructor); |
1558 { | 1569 { |
1559 FrameScope frame(masm, StackFrame::INTERNAL); | 1570 FrameScope frame(masm, StackFrame::INTERNAL); |
1560 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | 1571 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
1561 } | 1572 } |
1562 } | 1573 } |
1563 | 1574 |
1564 | 1575 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1838 } | 1849 } |
1839 } | 1850 } |
1840 | 1851 |
1841 | 1852 |
1842 #undef __ | 1853 #undef __ |
1843 | 1854 |
1844 } // namespace internal | 1855 } // namespace internal |
1845 } // namespace v8 | 1856 } // namespace v8 |
1846 | 1857 |
1847 #endif // V8_TARGET_ARCH_ARM | 1858 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |