OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, x10); | 175 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, x10); |
176 __ Cmp(function, x10); | 176 __ Cmp(function, x10); |
177 __ Assert(eq, kUnexpectedStringFunction); | 177 __ Assert(eq, kUnexpectedStringFunction); |
178 } | 178 } |
179 | 179 |
180 // Load the first arguments in x0 and get rid of the rest. | 180 // Load the first arguments in x0 and get rid of the rest. |
181 Label no_arguments; | 181 Label no_arguments; |
182 __ Cbz(argc, &no_arguments); | 182 __ Cbz(argc, &no_arguments); |
183 // First args = sp[(argc - 1) * 8]. | 183 // First args = sp[(argc - 1) * 8]. |
184 __ Sub(argc, argc, 1); | 184 __ Sub(argc, argc, 1); |
185 __ Claim(argc, kXRegSizeInBytes); | 185 __ Claim(argc, kXRegSize); |
186 // jssp now point to args[0], load and drop args[0] + receiver. | 186 // jssp now point to args[0], load and drop args[0] + receiver. |
187 Register arg = argc; | 187 Register arg = argc; |
188 __ Ldr(arg, MemOperand(jssp, 2 * kPointerSize, PostIndex)); | 188 __ Ldr(arg, MemOperand(jssp, 2 * kPointerSize, PostIndex)); |
189 argc = NoReg; | 189 argc = NoReg; |
190 | 190 |
191 Register argument = x2; | 191 Register argument = x2; |
192 Label not_cached, argument_is_string; | 192 Label not_cached, argument_is_string; |
193 __ LookupNumberStringCache(arg, // Input. | 193 __ LookupNumberStringCache(arg, // Input. |
194 argument, // Result. | 194 argument, // Result. |
195 x10, // Scratch. | 195 x10, // Scratch. |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 // x4: JSObject | 525 // x4: JSObject |
526 __ Bind(&allocated); | 526 __ Bind(&allocated); |
527 __ Push(x4, x4); | 527 __ Push(x4, x4); |
528 | 528 |
529 // Reload the number of arguments from the stack. | 529 // Reload the number of arguments from the stack. |
530 // Set it up in x0 for the function call below. | 530 // Set it up in x0 for the function call below. |
531 // jssp[0]: receiver | 531 // jssp[0]: receiver |
532 // jssp[1]: receiver | 532 // jssp[1]: receiver |
533 // jssp[2]: constructor function | 533 // jssp[2]: constructor function |
534 // jssp[3]: number of arguments (smi-tagged) | 534 // jssp[3]: number of arguments (smi-tagged) |
535 __ Peek(constructor, 2 * kXRegSizeInBytes); // Load constructor. | 535 __ Peek(constructor, 2 * kXRegSize); // Load constructor. |
536 __ Peek(argc, 3 * kXRegSizeInBytes); // Load number of arguments. | 536 __ Peek(argc, 3 * kXRegSize); // Load number of arguments. |
537 __ SmiUntag(argc); | 537 __ SmiUntag(argc); |
538 | 538 |
539 // Set up pointer to last argument. | 539 // Set up pointer to last argument. |
540 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); | 540 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); |
541 | 541 |
542 // Copy arguments and receiver to the expression stack. | 542 // Copy arguments and receiver to the expression stack. |
543 // Copy 2 values every loop to use ldp/stp. | 543 // Copy 2 values every loop to use ldp/stp. |
544 // x0: number of arguments | 544 // x0: number of arguments |
545 // x1: constructor function | 545 // x1: constructor function |
546 // x2: address of last argument (caller sp) | 546 // x2: address of last argument (caller sp) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 __ Bind(&use_receiver); | 610 __ Bind(&use_receiver); |
611 __ Peek(x0, 0); | 611 __ Peek(x0, 0); |
612 | 612 |
613 // Remove the receiver from the stack, remove caller arguments, and | 613 // Remove the receiver from the stack, remove caller arguments, and |
614 // return. | 614 // return. |
615 __ Bind(&exit); | 615 __ Bind(&exit); |
616 // x0: result | 616 // x0: result |
617 // jssp[0]: receiver (newly allocated object) | 617 // jssp[0]: receiver (newly allocated object) |
618 // jssp[1]: constructor function | 618 // jssp[1]: constructor function |
619 // jssp[2]: number of arguments (smi-tagged) | 619 // jssp[2]: number of arguments (smi-tagged) |
620 __ Peek(x1, 2 * kXRegSizeInBytes); | 620 __ Peek(x1, 2 * kXRegSize); |
621 | 621 |
622 // Leave construct frame. | 622 // Leave construct frame. |
623 } | 623 } |
624 | 624 |
625 __ DropBySMI(x1); | 625 __ DropBySMI(x1); |
626 __ Drop(1); | 626 __ Drop(1); |
627 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); | 627 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); |
628 __ Ret(); | 628 __ Ret(); |
629 } | 629 } |
630 | 630 |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 __ Cbnz(argc, &done); | 1010 __ Cbnz(argc, &done); |
1011 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex); | 1011 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex); |
1012 __ Push(scratch1); | 1012 __ Push(scratch1); |
1013 __ Mov(argc, 1); | 1013 __ Mov(argc, 1); |
1014 __ Bind(&done); | 1014 __ Bind(&done); |
1015 } | 1015 } |
1016 | 1016 |
1017 // 2. Get the function to call (passed as receiver) from the stack, check | 1017 // 2. Get the function to call (passed as receiver) from the stack, check |
1018 // if it is a function. | 1018 // if it is a function. |
1019 Label slow, non_function; | 1019 Label slow, non_function; |
1020 __ Peek(function, Operand(argc, LSL, kXRegSizeInBytesLog2)); | 1020 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); |
1021 __ JumpIfSmi(function, &non_function); | 1021 __ JumpIfSmi(function, &non_function); |
1022 __ JumpIfNotObjectType(function, scratch1, receiver_type, | 1022 __ JumpIfNotObjectType(function, scratch1, receiver_type, |
1023 JS_FUNCTION_TYPE, &slow); | 1023 JS_FUNCTION_TYPE, &slow); |
1024 | 1024 |
1025 // 3a. Patch the first argument if necessary when calling a function. | 1025 // 3a. Patch the first argument if necessary when calling a function. |
1026 Label shift_arguments; | 1026 Label shift_arguments; |
1027 __ Mov(call_type, static_cast<int>(call_type_JS_func)); | 1027 __ Mov(call_type, static_cast<int>(call_type_JS_func)); |
1028 { Label convert_to_object, use_global_receiver, patch_receiver; | 1028 { Label convert_to_object, use_global_receiver, patch_receiver; |
1029 // Change context eagerly in case we need the global receiver. | 1029 // Change context eagerly in case we need the global receiver. |
1030 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 1030 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); |
1031 | 1031 |
1032 // Do not transform the receiver for strict mode functions. | 1032 // Do not transform the receiver for strict mode functions. |
1033 // Also do not transform the receiver for native (Compilerhints already in | 1033 // Also do not transform the receiver for native (Compilerhints already in |
1034 // x3). | 1034 // x3). |
1035 __ Ldr(scratch1, | 1035 __ Ldr(scratch1, |
1036 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 1036 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
1037 __ Ldr(scratch2.W(), | 1037 __ Ldr(scratch2.W(), |
1038 FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset)); | 1038 FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset)); |
1039 __ TestAndBranchIfAnySet( | 1039 __ TestAndBranchIfAnySet( |
1040 scratch2.W(), | 1040 scratch2.W(), |
1041 (1 << SharedFunctionInfo::kStrictModeFunction) | | 1041 (1 << SharedFunctionInfo::kStrictModeFunction) | |
1042 (1 << SharedFunctionInfo::kNative), | 1042 (1 << SharedFunctionInfo::kNative), |
1043 &shift_arguments); | 1043 &shift_arguments); |
1044 | 1044 |
1045 // Compute the receiver in non-strict mode. | 1045 // Compute the receiver in non-strict mode. |
1046 Register receiver = x2; | 1046 Register receiver = x2; |
1047 __ Sub(scratch1, argc, 1); | 1047 __ Sub(scratch1, argc, 1); |
1048 __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeInBytesLog2)); | 1048 __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); |
1049 __ JumpIfSmi(receiver, &convert_to_object); | 1049 __ JumpIfSmi(receiver, &convert_to_object); |
1050 | 1050 |
1051 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, | 1051 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, |
1052 &use_global_receiver); | 1052 &use_global_receiver); |
1053 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver); | 1053 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver); |
1054 | 1054 |
1055 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 1055 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |
1056 __ JumpIfObjectType(receiver, scratch1, scratch2, | 1056 __ JumpIfObjectType(receiver, scratch1, scratch2, |
1057 FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge); | 1057 FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge); |
1058 | 1058 |
1059 __ Bind(&convert_to_object); | 1059 __ Bind(&convert_to_object); |
1060 | 1060 |
1061 { | 1061 { |
1062 // Enter an internal frame in order to preserve argument count. | 1062 // Enter an internal frame in order to preserve argument count. |
1063 FrameScope scope(masm, StackFrame::INTERNAL); | 1063 FrameScope scope(masm, StackFrame::INTERNAL); |
1064 __ SmiTag(argc); | 1064 __ SmiTag(argc); |
1065 | 1065 |
1066 __ Push(argc, receiver); | 1066 __ Push(argc, receiver); |
1067 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 1067 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
1068 __ Mov(receiver, x0); | 1068 __ Mov(receiver, x0); |
1069 | 1069 |
1070 __ Pop(argc); | 1070 __ Pop(argc); |
1071 __ SmiUntag(argc); | 1071 __ SmiUntag(argc); |
1072 | 1072 |
1073 // Exit the internal frame. | 1073 // Exit the internal frame. |
1074 } | 1074 } |
1075 | 1075 |
1076 // Restore the function and flag in the registers. | 1076 // Restore the function and flag in the registers. |
1077 __ Peek(function, Operand(argc, LSL, kXRegSizeInBytesLog2)); | 1077 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); |
1078 __ Mov(call_type, static_cast<int>(call_type_JS_func)); | 1078 __ Mov(call_type, static_cast<int>(call_type_JS_func)); |
1079 __ B(&patch_receiver); | 1079 __ B(&patch_receiver); |
1080 | 1080 |
1081 __ Bind(&use_global_receiver); | 1081 __ Bind(&use_global_receiver); |
1082 __ Ldr(receiver, GlobalObjectMemOperand()); | 1082 __ Ldr(receiver, GlobalObjectMemOperand()); |
1083 __ Ldr(receiver, | 1083 __ Ldr(receiver, |
1084 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); | 1084 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); |
1085 | 1085 |
1086 | 1086 |
1087 __ Bind(&patch_receiver); | 1087 __ Bind(&patch_receiver); |
1088 __ Sub(scratch1, argc, 1); | 1088 __ Sub(scratch1, argc, 1); |
1089 __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeInBytesLog2)); | 1089 __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); |
1090 | 1090 |
1091 __ B(&shift_arguments); | 1091 __ B(&shift_arguments); |
1092 } | 1092 } |
1093 | 1093 |
1094 // 3b. Check for function proxy. | 1094 // 3b. Check for function proxy. |
1095 __ Bind(&slow); | 1095 __ Bind(&slow); |
1096 __ Mov(call_type, static_cast<int>(call_type_func_proxy)); | 1096 __ Mov(call_type, static_cast<int>(call_type_func_proxy)); |
1097 __ Cmp(receiver_type, JS_FUNCTION_PROXY_TYPE); | 1097 __ Cmp(receiver_type, JS_FUNCTION_PROXY_TYPE); |
1098 __ B(eq, &shift_arguments); | 1098 __ B(eq, &shift_arguments); |
1099 __ Bind(&non_function); | 1099 __ Bind(&non_function); |
1100 __ Mov(call_type, static_cast<int>(call_type_non_func)); | 1100 __ Mov(call_type, static_cast<int>(call_type_non_func)); |
1101 | 1101 |
1102 // 3c. Patch the first argument when calling a non-function. The | 1102 // 3c. Patch the first argument when calling a non-function. The |
1103 // CALL_NON_FUNCTION builtin expects the non-function callee as | 1103 // CALL_NON_FUNCTION builtin expects the non-function callee as |
1104 // receiver, so overwrite the first argument which will ultimately | 1104 // receiver, so overwrite the first argument which will ultimately |
1105 // become the receiver. | 1105 // become the receiver. |
1106 // call type (0: JS function, 1: function proxy, 2: non-function) | 1106 // call type (0: JS function, 1: function proxy, 2: non-function) |
1107 __ Sub(scratch1, argc, 1); | 1107 __ Sub(scratch1, argc, 1); |
1108 __ Poke(function, Operand(scratch1, LSL, kXRegSizeInBytesLog2)); | 1108 __ Poke(function, Operand(scratch1, LSL, kXRegSizeLog2)); |
1109 | 1109 |
1110 // 4. Shift arguments and return address one slot down on the stack | 1110 // 4. Shift arguments and return address one slot down on the stack |
1111 // (overwriting the original receiver). Adjust argument count to make | 1111 // (overwriting the original receiver). Adjust argument count to make |
1112 // the original first argument the new receiver. | 1112 // the original first argument the new receiver. |
1113 // call type (0: JS function, 1: function proxy, 2: non-function) | 1113 // call type (0: JS function, 1: function proxy, 2: non-function) |
1114 __ Bind(&shift_arguments); | 1114 __ Bind(&shift_arguments); |
1115 { Label loop; | 1115 { Label loop; |
1116 // Calculate the copy start address (destination). Copy end address is jssp. | 1116 // Calculate the copy start address (destination). Copy end address is jssp. |
1117 __ Add(scratch2, jssp, Operand(argc, LSL, kPointerSizeLog2)); | 1117 __ Add(scratch2, jssp, Operand(argc, LSL, kPointerSizeLog2)); |
1118 __ Sub(scratch1, scratch2, kPointerSize); | 1118 __ Sub(scratch1, scratch2, kPointerSize); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 1344 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
1345 // ----------- S t a t e ------------- | 1345 // ----------- S t a t e ------------- |
1346 // -- x0 : result being passed through | 1346 // -- x0 : result being passed through |
1347 // ----------------------------------- | 1347 // ----------------------------------- |
1348 // Get the number of arguments passed (as a smi), tear down the frame and | 1348 // Get the number of arguments passed (as a smi), tear down the frame and |
1349 // then drop the parameters and the receiver. | 1349 // then drop the parameters and the receiver. |
1350 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 1350 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + |
1351 kPointerSize))); | 1351 kPointerSize))); |
1352 __ Mov(jssp, fp); | 1352 __ Mov(jssp, fp); |
1353 __ Pop(fp, lr); | 1353 __ Pop(fp, lr); |
1354 __ DropBySMI(x10, kXRegSizeInBytes); | 1354 __ DropBySMI(x10, kXRegSize); |
1355 __ Drop(1); | 1355 __ Drop(1); |
1356 } | 1356 } |
1357 | 1357 |
1358 | 1358 |
1359 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1359 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1360 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); | 1360 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); |
1361 // ----------- S t a t e ------------- | 1361 // ----------- S t a t e ------------- |
1362 // -- x0 : actual number of arguments | 1362 // -- x0 : actual number of arguments |
1363 // -- x1 : function (passed through to callee) | 1363 // -- x1 : function (passed through to callee) |
1364 // -- x2 : expected number of arguments | 1364 // -- x2 : expected number of arguments |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 __ Bind(&dont_adapt_arguments); | 1484 __ Bind(&dont_adapt_arguments); |
1485 __ Jump(code_entry); | 1485 __ Jump(code_entry); |
1486 } | 1486 } |
1487 | 1487 |
1488 | 1488 |
1489 #undef __ | 1489 #undef __ |
1490 | 1490 |
1491 } } // namespace v8::internal | 1491 } } // namespace v8::internal |
1492 | 1492 |
1493 #endif // V8_TARGET_ARCH_ARM | 1493 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |