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