| 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 |