| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 __ b(ne, &convert_argument); | 254 __ b(ne, &convert_argument); |
| 255 __ mov(argument, r0); | 255 __ mov(argument, r0); |
| 256 __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); | 256 __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); |
| 257 __ b(&argument_is_string); | 257 __ b(&argument_is_string); |
| 258 | 258 |
| 259 // Invoke the conversion builtin and put the result into r2. | 259 // Invoke the conversion builtin and put the result into r2. |
| 260 __ bind(&convert_argument); | 260 __ bind(&convert_argument); |
| 261 __ push(function); // Preserve the function. | 261 __ push(function); // Preserve the function. |
| 262 __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); | 262 __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); |
| 263 { | 263 { |
| 264 FrameScope scope(masm, StackFrame::INTERNAL); | 264 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 265 __ push(r0); | 265 __ push(r0); |
| 266 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); | 266 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); |
| 267 } | 267 } |
| 268 __ pop(function); | 268 __ pop(function); |
| 269 __ mov(argument, r0); | 269 __ mov(argument, r0); |
| 270 __ b(&argument_is_string); | 270 __ b(&argument_is_string); |
| 271 | 271 |
| 272 // Load the empty string into r2, remove the receiver from the | 272 // Load the empty string into r2, remove the receiver from the |
| 273 // stack, and jump back to the case where the argument is a string. | 273 // stack, and jump back to the case where the argument is a string. |
| 274 __ bind(&no_arguments); | 274 __ bind(&no_arguments); |
| 275 __ LoadRoot(argument, Heap::kempty_stringRootIndex); | 275 __ LoadRoot(argument, Heap::kempty_stringRootIndex); |
| 276 __ Drop(1); | 276 __ Drop(1); |
| 277 __ b(&argument_is_string); | 277 __ b(&argument_is_string); |
| 278 | 278 |
| 279 // At this point the argument is already a string. Call runtime to | 279 // At this point the argument is already a string. Call runtime to |
| 280 // create a string wrapper. | 280 // create a string wrapper. |
| 281 __ bind(&gc_required); | 281 __ bind(&gc_required); |
| 282 __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4); | 282 __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4); |
| 283 { | 283 { |
| 284 FrameScope scope(masm, StackFrame::INTERNAL); | 284 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 285 __ push(argument); | 285 __ push(argument); |
| 286 __ CallRuntime(Runtime::kNewStringWrapper, 1); | 286 __ CallRuntime(Runtime::kNewStringWrapper, 1); |
| 287 } | 287 } |
| 288 __ Ret(); | 288 __ Ret(); |
| 289 } | 289 } |
| 290 | 290 |
| 291 | 291 |
| 292 static void CallRuntimePassFunction( | 292 static void CallRuntimePassFunction( |
| 293 MacroAssembler* masm, Runtime::FunctionId function_id) { | 293 MacroAssembler* masm, Runtime::FunctionId function_id) { |
| 294 FrameScope scope(masm, StackFrame::INTERNAL); | 294 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 295 // Push a copy of the function onto the stack. | 295 // Push a copy of the function onto the stack. |
| 296 __ push(r1); | 296 __ push(r1); |
| 297 // Push function as parameter to the runtime call. | 297 // Push function as parameter to the runtime call. |
| 298 __ Push(r1); | 298 __ Push(r1); |
| 299 | 299 |
| 300 __ CallRuntime(function_id, 1); | 300 __ CallRuntime(function_id, 1); |
| 301 // Restore receiver. | 301 // Restore receiver. |
| 302 __ pop(r1); | 302 __ pop(r1); |
| 303 } | 303 } |
| 304 | 304 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 // -- sp[...]: constructor arguments | 346 // -- sp[...]: constructor arguments |
| 347 // ----------------------------------- | 347 // ----------------------------------- |
| 348 | 348 |
| 349 // Should never count constructions for api objects. | 349 // Should never count constructions for api objects. |
| 350 ASSERT(!is_api_function || !count_constructions); | 350 ASSERT(!is_api_function || !count_constructions); |
| 351 | 351 |
| 352 Isolate* isolate = masm->isolate(); | 352 Isolate* isolate = masm->isolate(); |
| 353 | 353 |
| 354 // Enter a construct frame. | 354 // Enter a construct frame. |
| 355 { | 355 { |
| 356 FrameScope scope(masm, StackFrame::CONSTRUCT); | 356 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); |
| 357 | 357 |
| 358 // Preserve the two incoming parameters on the stack. | 358 // Preserve the two incoming parameters on the stack. |
| 359 __ SmiTag(r0); | 359 __ SmiTag(r0); |
| 360 __ push(r0); // Smi-tagged arguments count. | 360 __ push(r0); // Smi-tagged arguments count. |
| 361 __ push(r1); // Constructor function. | 361 __ push(r1); // Constructor function. |
| 362 | 362 |
| 363 // Try to allocate the object without transitioning into C code. If any of | 363 // Try to allocate the object without transitioning into C code. If any of |
| 364 // the preconditions is not met, the code bails out to the runtime call. | 364 // the preconditions is not met, the code bails out to the runtime call. |
| 365 Label rt_call, allocated; | 365 Label rt_call, allocated; |
| 366 if (FLAG_inline_new) { | 366 if (FLAG_inline_new) { |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 } | 766 } |
| 767 | 767 |
| 768 | 768 |
| 769 void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) { | 769 void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) { |
| 770 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); | 770 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); |
| 771 GenerateTailCallToReturnedCode(masm); | 771 GenerateTailCallToReturnedCode(masm); |
| 772 } | 772 } |
| 773 | 773 |
| 774 | 774 |
| 775 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { | 775 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { |
| 776 FrameScope scope(masm, StackFrame::INTERNAL); | 776 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 777 // Push a copy of the function onto the stack. | 777 // Push a copy of the function onto the stack. |
| 778 __ push(r1); | 778 __ push(r1); |
| 779 // Push function as parameter to the runtime call. | 779 // Push function as parameter to the runtime call. |
| 780 __ Push(r1); | 780 __ Push(r1); |
| 781 // Whether to compile in a background thread. | 781 // Whether to compile in a background thread. |
| 782 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); | 782 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); |
| 783 | 783 |
| 784 __ CallRuntime(Runtime::kCompileOptimized, 2); | 784 __ CallRuntime(Runtime::kCompileOptimized, 2); |
| 785 // Restore receiver. | 785 // Restore receiver. |
| 786 __ pop(r1); | 786 __ pop(r1); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 | 862 |
| 863 | 863 |
| 864 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 864 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
| 865 GenerateMakeCodeYoungAgainCommon(masm); | 865 GenerateMakeCodeYoungAgainCommon(masm); |
| 866 } | 866 } |
| 867 | 867 |
| 868 | 868 |
| 869 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 869 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
| 870 SaveFPRegsMode save_doubles) { | 870 SaveFPRegsMode save_doubles) { |
| 871 { | 871 { |
| 872 FrameScope scope(masm, StackFrame::INTERNAL); | 872 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 873 | 873 |
| 874 // Preserve registers across notification, this is important for compiled | 874 // Preserve registers across notification, this is important for compiled |
| 875 // stubs that tail call the runtime on deopts passing their parameters in | 875 // stubs that tail call the runtime on deopts passing their parameters in |
| 876 // registers. | 876 // registers. |
| 877 __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved); | 877 __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved); |
| 878 // Pass the function and deoptimization type to the runtime system. | 878 // Pass the function and deoptimization type to the runtime system. |
| 879 __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); | 879 __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); |
| 880 __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved); | 880 __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved); |
| 881 } | 881 } |
| 882 | 882 |
| 883 __ add(sp, sp, Operand(kPointerSize)); // Ignore state | 883 __ add(sp, sp, Operand(kPointerSize)); // Ignore state |
| 884 __ mov(pc, lr); // Jump to miss handler | 884 __ mov(pc, lr); // Jump to miss handler |
| 885 } | 885 } |
| 886 | 886 |
| 887 | 887 |
| 888 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 888 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
| 889 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 889 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
| 890 } | 890 } |
| 891 | 891 |
| 892 | 892 |
| 893 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 893 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
| 894 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 894 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
| 895 } | 895 } |
| 896 | 896 |
| 897 | 897 |
| 898 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 898 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
| 899 Deoptimizer::BailoutType type) { | 899 Deoptimizer::BailoutType type) { |
| 900 { | 900 { |
| 901 FrameScope scope(masm, StackFrame::INTERNAL); | 901 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 902 // Pass the function and deoptimization type to the runtime system. | 902 // Pass the function and deoptimization type to the runtime system. |
| 903 __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type)))); | 903 __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type)))); |
| 904 __ push(r0); | 904 __ push(r0); |
| 905 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); | 905 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); |
| 906 } | 906 } |
| 907 | 907 |
| 908 // Get the full codegen state from the stack and untag it -> r6. | 908 // Get the full codegen state from the stack and untag it -> r6. |
| 909 __ ldr(r6, MemOperand(sp, 0 * kPointerSize)); | 909 __ ldr(r6, MemOperand(sp, 0 * kPointerSize)); |
| 910 __ SmiUntag(r6); | 910 __ SmiUntag(r6); |
| 911 // Switch on the state. | 911 // Switch on the state. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 939 | 939 |
| 940 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 940 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
| 941 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 941 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
| 942 } | 942 } |
| 943 | 943 |
| 944 | 944 |
| 945 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 945 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 946 // Lookup the function in the JavaScript frame. | 946 // Lookup the function in the JavaScript frame. |
| 947 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 947 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 948 { | 948 { |
| 949 FrameScope scope(masm, StackFrame::INTERNAL); | 949 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 950 // Pass function as argument. | 950 // Pass function as argument. |
| 951 __ push(r0); | 951 __ push(r0); |
| 952 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 952 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); |
| 953 } | 953 } |
| 954 | 954 |
| 955 // If the code object is null, just return to the unoptimized code. | 955 // If the code object is null, just return to the unoptimized code. |
| 956 Label skip; | 956 Label skip; |
| 957 __ cmp(r0, Operand(Smi::FromInt(0))); | 957 __ cmp(r0, Operand(Smi::FromInt(0))); |
| 958 __ b(ne, &skip); | 958 __ b(ne, &skip); |
| 959 __ Ret(); | 959 __ Ret(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 979 } | 979 } |
| 980 | 980 |
| 981 | 981 |
| 982 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { | 982 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { |
| 983 // We check the stack limit as indicator that recompilation might be done. | 983 // We check the stack limit as indicator that recompilation might be done. |
| 984 Label ok; | 984 Label ok; |
| 985 __ LoadRoot(ip, Heap::kStackLimitRootIndex); | 985 __ LoadRoot(ip, Heap::kStackLimitRootIndex); |
| 986 __ cmp(sp, Operand(ip)); | 986 __ cmp(sp, Operand(ip)); |
| 987 __ b(hs, &ok); | 987 __ b(hs, &ok); |
| 988 { | 988 { |
| 989 FrameScope scope(masm, StackFrame::INTERNAL); | 989 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 990 __ CallRuntime(Runtime::kStackGuard, 0); | 990 __ CallRuntime(Runtime::kStackGuard, 0); |
| 991 } | 991 } |
| 992 __ Jump(masm->isolate()->builtins()->OnStackReplacement(), | 992 __ Jump(masm->isolate()->builtins()->OnStackReplacement(), |
| 993 RelocInfo::CODE_TARGET); | 993 RelocInfo::CODE_TARGET); |
| 994 | 994 |
| 995 __ bind(&ok); | 995 __ bind(&ok); |
| 996 __ Ret(); | 996 __ Ret(); |
| 997 } | 997 } |
| 998 | 998 |
| 999 | 999 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 __ b(eq, &use_global_receiver); | 1054 __ b(eq, &use_global_receiver); |
| 1055 | 1055 |
| 1056 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 1056 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |
| 1057 __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE); | 1057 __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE); |
| 1058 __ b(ge, &shift_arguments); | 1058 __ b(ge, &shift_arguments); |
| 1059 | 1059 |
| 1060 __ bind(&convert_to_object); | 1060 __ bind(&convert_to_object); |
| 1061 | 1061 |
| 1062 { | 1062 { |
| 1063 // Enter an internal frame in order to preserve argument count. | 1063 // Enter an internal frame in order to preserve argument count. |
| 1064 FrameScope scope(masm, StackFrame::INTERNAL); | 1064 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 1065 __ SmiTag(r0); | 1065 __ SmiTag(r0); |
| 1066 __ push(r0); | 1066 __ push(r0); |
| 1067 | 1067 |
| 1068 __ push(r2); | 1068 __ push(r2); |
| 1069 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 1069 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 1070 __ mov(r2, r0); | 1070 __ mov(r2, r0); |
| 1071 | 1071 |
| 1072 __ pop(r0); | 1072 __ pop(r0); |
| 1073 __ SmiUntag(r0); | 1073 __ SmiUntag(r0); |
| 1074 | 1074 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 1181 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
| 1182 const int kIndexOffset = | 1182 const int kIndexOffset = |
| 1183 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1183 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
| 1184 const int kLimitOffset = | 1184 const int kLimitOffset = |
| 1185 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1185 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
| 1186 const int kArgsOffset = 2 * kPointerSize; | 1186 const int kArgsOffset = 2 * kPointerSize; |
| 1187 const int kRecvOffset = 3 * kPointerSize; | 1187 const int kRecvOffset = 3 * kPointerSize; |
| 1188 const int kFunctionOffset = 4 * kPointerSize; | 1188 const int kFunctionOffset = 4 * kPointerSize; |
| 1189 | 1189 |
| 1190 { | 1190 { |
| 1191 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1191 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); |
| 1192 | 1192 |
| 1193 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function | 1193 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function |
| 1194 __ push(r0); | 1194 __ push(r0); |
| 1195 __ ldr(r0, MemOperand(fp, kArgsOffset)); // get the args array | 1195 __ ldr(r0, MemOperand(fp, kArgsOffset)); // get the args array |
| 1196 __ push(r0); | 1196 __ push(r0); |
| 1197 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1197 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
| 1198 | 1198 |
| 1199 // Check the stack for overflow. We are not trying to catch | 1199 // Check the stack for overflow. We are not trying to catch |
| 1200 // interruptions (e.g. debug break and preemption) here, so the "real stack | 1200 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 1201 // limit" is checked. | 1201 // limit" is checked. |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 __ bind(&dont_adapt_arguments); | 1467 __ bind(&dont_adapt_arguments); |
| 1468 __ Jump(r3); | 1468 __ Jump(r3); |
| 1469 } | 1469 } |
| 1470 | 1470 |
| 1471 | 1471 |
| 1472 #undef __ | 1472 #undef __ |
| 1473 | 1473 |
| 1474 } } // namespace v8::internal | 1474 } } // namespace v8::internal |
| 1475 | 1475 |
| 1476 #endif // V8_TARGET_ARCH_ARM | 1476 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |