| 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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.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" |
| 11 #include "src/ia32/frames-ia32.h" | 11 #include "src/ia32/frames-ia32.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 | |
| 17 #define __ ACCESS_MASM(masm) | 16 #define __ ACCESS_MASM(masm) |
| 18 | 17 |
| 19 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, | 18 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, |
| 20 ExitFrameType exit_frame_type) { | 19 ExitFrameType exit_frame_type) { |
| 21 // ----------- S t a t e ------------- | 20 // ----------- S t a t e ------------- |
| 22 // -- eax : number of arguments excluding receiver | 21 // -- eax : number of arguments excluding receiver |
| 23 // -- edi : target | 22 // -- edi : target |
| 24 // -- edx : new.target | 23 // -- edx : new.target |
| 25 // -- esp[0] : return address | 24 // -- esp[0] : return address |
| 26 // -- esp[4] : last argument | 25 // -- esp[4] : last argument |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 237 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 239 __ pop(ecx); | 238 __ pop(ecx); |
| 240 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 239 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
| 241 __ push(ecx); | 240 __ push(ecx); |
| 242 if (create_implicit_receiver) { | 241 if (create_implicit_receiver) { |
| 243 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); | 242 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); |
| 244 } | 243 } |
| 245 __ ret(0); | 244 __ ret(0); |
| 246 } | 245 } |
| 247 | 246 |
| 248 | |
| 249 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 247 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 250 Generate_JSConstructStubHelper(masm, false, true, false); | 248 Generate_JSConstructStubHelper(masm, false, true, false); |
| 251 } | 249 } |
| 252 | 250 |
| 253 | |
| 254 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 251 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 255 Generate_JSConstructStubHelper(masm, true, false, false); | 252 Generate_JSConstructStubHelper(masm, true, false, false); |
| 256 } | 253 } |
| 257 | 254 |
| 258 | |
| 259 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 255 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
| 260 Generate_JSConstructStubHelper(masm, false, false, false); | 256 Generate_JSConstructStubHelper(masm, false, false, false); |
| 261 } | 257 } |
| 262 | 258 |
| 263 | |
| 264 void Builtins::Generate_JSBuiltinsConstructStubForDerived( | 259 void Builtins::Generate_JSBuiltinsConstructStubForDerived( |
| 265 MacroAssembler* masm) { | 260 MacroAssembler* masm) { |
| 266 Generate_JSConstructStubHelper(masm, false, false, true); | 261 Generate_JSConstructStubHelper(masm, false, false, true); |
| 267 } | 262 } |
| 268 | 263 |
| 269 | |
| 270 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { | 264 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { |
| 271 FrameScope scope(masm, StackFrame::INTERNAL); | 265 FrameScope scope(masm, StackFrame::INTERNAL); |
| 272 __ push(edi); | 266 __ push(edi); |
| 273 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); | 267 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); |
| 274 } | 268 } |
| 275 | 269 |
| 276 | |
| 277 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; | 270 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; |
| 278 | 271 |
| 279 | |
| 280 // Clobbers ecx, edx, edi; preserves all other registers. | 272 // Clobbers ecx, edx, edi; preserves all other registers. |
| 281 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 273 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
| 282 IsTagged eax_is_tagged) { | 274 IsTagged eax_is_tagged) { |
| 283 // eax : the number of items to be pushed to the stack | 275 // eax : the number of items to be pushed to the stack |
| 284 // | 276 // |
| 285 // Check the stack for overflow. We are not trying to catch | 277 // Check the stack for overflow. We are not trying to catch |
| 286 // interruptions (e.g. debug break and preemption) here, so the "real stack | 278 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 287 // limit" is checked. | 279 // limit" is checked. |
| 288 Label okay; | 280 Label okay; |
| 289 ExternalReference real_stack_limit = | 281 ExternalReference real_stack_limit = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 301 // Check if the arguments will overflow the stack. | 293 // Check if the arguments will overflow the stack. |
| 302 __ cmp(ecx, edx); | 294 __ cmp(ecx, edx); |
| 303 __ j(greater, &okay); // Signed comparison. | 295 __ j(greater, &okay); // Signed comparison. |
| 304 | 296 |
| 305 // Out of stack space. | 297 // Out of stack space. |
| 306 __ CallRuntime(Runtime::kThrowStackOverflow); | 298 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 307 | 299 |
| 308 __ bind(&okay); | 300 __ bind(&okay); |
| 309 } | 301 } |
| 310 | 302 |
| 311 | |
| 312 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 303 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
| 313 bool is_construct) { | 304 bool is_construct) { |
| 314 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 305 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 315 | 306 |
| 316 { | 307 { |
| 317 FrameScope scope(masm, StackFrame::INTERNAL); | 308 FrameScope scope(masm, StackFrame::INTERNAL); |
| 318 | 309 |
| 319 // Setup the context (we need to use the caller context from the isolate). | 310 // Setup the context (we need to use the caller context from the isolate). |
| 320 ExternalReference context_address(Isolate::kContextAddress, | 311 ExternalReference context_address(Isolate::kContextAddress, |
| 321 masm->isolate()); | 312 masm->isolate()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 335 // Check if we have enough stack space to push all arguments. | 326 // Check if we have enough stack space to push all arguments. |
| 336 // Expects argument count in eax. Clobbers ecx, edx, edi. | 327 // Expects argument count in eax. Clobbers ecx, edx, edi. |
| 337 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); | 328 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); |
| 338 | 329 |
| 339 // Copy arguments to the stack in a loop. | 330 // Copy arguments to the stack in a loop. |
| 340 Label loop, entry; | 331 Label loop, entry; |
| 341 __ Move(ecx, Immediate(0)); | 332 __ Move(ecx, Immediate(0)); |
| 342 __ jmp(&entry, Label::kNear); | 333 __ jmp(&entry, Label::kNear); |
| 343 __ bind(&loop); | 334 __ bind(&loop); |
| 344 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv | 335 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv |
| 345 __ push(Operand(edx, 0)); // dereference handle | 336 __ push(Operand(edx, 0)); // dereference handle |
| 346 __ inc(ecx); | 337 __ inc(ecx); |
| 347 __ bind(&entry); | 338 __ bind(&entry); |
| 348 __ cmp(ecx, eax); | 339 __ cmp(ecx, eax); |
| 349 __ j(not_equal, &loop); | 340 __ j(not_equal, &loop); |
| 350 | 341 |
| 351 // Load the previous frame pointer (ebx) to access C arguments | 342 // Load the previous frame pointer (ebx) to access C arguments |
| 352 __ mov(ebx, Operand(ebp, 0)); | 343 __ mov(ebx, Operand(ebp, 0)); |
| 353 | 344 |
| 354 // Get the new.target and function from the frame. | 345 // Get the new.target and function from the frame. |
| 355 __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset)); | 346 __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset)); |
| 356 __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); | 347 __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); |
| 357 | 348 |
| 358 // Invoke the code. | 349 // Invoke the code. |
| 359 Handle<Code> builtin = is_construct | 350 Handle<Code> builtin = is_construct |
| 360 ? masm->isolate()->builtins()->Construct() | 351 ? masm->isolate()->builtins()->Construct() |
| 361 : masm->isolate()->builtins()->Call(); | 352 : masm->isolate()->builtins()->Call(); |
| 362 __ Call(builtin, RelocInfo::CODE_TARGET); | 353 __ Call(builtin, RelocInfo::CODE_TARGET); |
| 363 | 354 |
| 364 // Exit the internal frame. Notice that this also removes the empty. | 355 // Exit the internal frame. Notice that this also removes the empty. |
| 365 // context and the function left on the stack by the code | 356 // context and the function left on the stack by the code |
| 366 // invocation. | 357 // invocation. |
| 367 } | 358 } |
| 368 __ ret(kPointerSize); // Remove receiver. | 359 __ ret(kPointerSize); // Remove receiver. |
| 369 } | 360 } |
| 370 | 361 |
| 371 | |
| 372 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 362 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
| 373 Generate_JSEntryTrampolineHelper(masm, false); | 363 Generate_JSEntryTrampolineHelper(masm, false); |
| 374 } | 364 } |
| 375 | 365 |
| 376 | |
| 377 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 366 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
| 378 Generate_JSEntryTrampolineHelper(masm, true); | 367 Generate_JSEntryTrampolineHelper(masm, true); |
| 379 } | 368 } |
| 380 | 369 |
| 381 // static | 370 // static |
| 382 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { | 371 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { |
| 383 // ----------- S t a t e ------------- | 372 // ----------- S t a t e ------------- |
| 384 // -- eax : the value to pass to the generator | 373 // -- eax : the value to pass to the generator |
| 385 // -- ebx : the JSGeneratorObject to resume | 374 // -- ebx : the JSGeneratorObject to resume |
| 386 // -- edx : the resume mode (tagged) | 375 // -- edx : the resume mode (tagged) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 442 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 454 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset)); | 443 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset)); |
| 455 __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx); | 444 __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx); |
| 456 __ j(not_equal, &old_generator); | 445 __ j(not_equal, &old_generator); |
| 457 | 446 |
| 458 // New-style (ignition/turbofan) generator object | 447 // New-style (ignition/turbofan) generator object |
| 459 { | 448 { |
| 460 __ PushReturnAddressFrom(eax); | 449 __ PushReturnAddressFrom(eax); |
| 461 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 450 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 462 __ mov(eax, | 451 __ mov(eax, |
| 463 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); | 452 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 464 // We abuse new.target both to indicate that this is a resume call and to | 453 // We abuse new.target both to indicate that this is a resume call and to |
| 465 // pass in the generator object. In ordinary calls, new.target is always | 454 // pass in the generator object. In ordinary calls, new.target is always |
| 466 // undefined because generator functions are non-constructable. | 455 // undefined because generator functions are non-constructable. |
| 467 __ mov(edx, ebx); | 456 __ mov(edx, ebx); |
| 468 __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 457 __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 469 } | 458 } |
| 470 | 459 |
| 471 // Old-style (full-codegen) generator object | 460 // Old-style (full-codegen) generator object |
| 472 __ bind(&old_generator); | 461 __ bind(&old_generator); |
| 473 { | 462 { |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 tail_call_mode), | 750 tail_call_mode), |
| 762 RelocInfo::CODE_TARGET); | 751 RelocInfo::CODE_TARGET); |
| 763 } else { | 752 } else { |
| 764 DCHECK_EQ(function_type, CallableType::kAny); | 753 DCHECK_EQ(function_type, CallableType::kAny); |
| 765 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 754 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 766 tail_call_mode), | 755 tail_call_mode), |
| 767 RelocInfo::CODE_TARGET); | 756 RelocInfo::CODE_TARGET); |
| 768 } | 757 } |
| 769 } | 758 } |
| 770 | 759 |
| 771 | |
| 772 // static | 760 // static |
| 773 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 761 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
| 774 // ----------- S t a t e ------------- | 762 // ----------- S t a t e ------------- |
| 775 // -- eax : the number of arguments (not including the receiver) | 763 // -- eax : the number of arguments (not including the receiver) |
| 776 // -- edx : the new target | 764 // -- edx : the new target |
| 777 // -- edi : the constructor | 765 // -- edi : the constructor |
| 778 // -- ebx : the address of the first argument to be pushed. Subsequent | 766 // -- ebx : the address of the first argument to be pushed. Subsequent |
| 779 // arguments should be consecutive above this, in the same order as | 767 // arguments should be consecutive above this, in the same order as |
| 780 // they are to be pushed onto the stack. | 768 // they are to be pushed onto the stack. |
| 781 // ----------------------------------- | 769 // ----------------------------------- |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 | 1007 |
| 1020 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { | 1008 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { |
| 1021 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); | 1009 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); |
| 1022 } | 1010 } |
| 1023 | 1011 |
| 1024 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 1012 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
| 1025 GenerateTailCallToReturnedCode(masm, | 1013 GenerateTailCallToReturnedCode(masm, |
| 1026 Runtime::kCompileOptimized_NotConcurrent); | 1014 Runtime::kCompileOptimized_NotConcurrent); |
| 1027 } | 1015 } |
| 1028 | 1016 |
| 1029 | |
| 1030 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 1017 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { |
| 1031 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); | 1018 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); |
| 1032 } | 1019 } |
| 1033 | 1020 |
| 1034 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { | 1021 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { |
| 1035 // ----------- S t a t e ------------- | 1022 // ----------- S t a t e ------------- |
| 1036 // -- eax : argument count (preserved for callee) | 1023 // -- eax : argument count (preserved for callee) |
| 1037 // -- edx : new target (preserved for callee) | 1024 // -- edx : new target (preserved for callee) |
| 1038 // -- edi : target function (preserved for callee) | 1025 // -- edi : target function (preserved for callee) |
| 1039 // ----------------------------------- | 1026 // ----------------------------------- |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 __ mov(Operand(esp, 1 * kPointerSize), | 1077 __ mov(Operand(esp, 1 * kPointerSize), |
| 1091 Immediate(ExternalReference::isolate_address(masm->isolate()))); | 1078 Immediate(ExternalReference::isolate_address(masm->isolate()))); |
| 1092 __ mov(Operand(esp, 0), eax); | 1079 __ mov(Operand(esp, 0), eax); |
| 1093 __ CallCFunction( | 1080 __ CallCFunction( |
| 1094 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 1081 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
| 1095 } | 1082 } |
| 1096 __ popad(); | 1083 __ popad(); |
| 1097 __ ret(0); | 1084 __ ret(0); |
| 1098 } | 1085 } |
| 1099 | 1086 |
| 1100 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ | 1087 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ |
| 1101 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ | 1088 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ |
| 1102 MacroAssembler* masm) { \ | 1089 MacroAssembler* masm) { \ |
| 1103 GenerateMakeCodeYoungAgainCommon(masm); \ | 1090 GenerateMakeCodeYoungAgainCommon(masm); \ |
| 1104 } \ | 1091 } \ |
| 1105 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ | 1092 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ |
| 1106 MacroAssembler* masm) { \ | 1093 MacroAssembler* masm) { \ |
| 1107 GenerateMakeCodeYoungAgainCommon(masm); \ | 1094 GenerateMakeCodeYoungAgainCommon(masm); \ |
| 1108 } | 1095 } |
| 1109 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) | 1096 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) |
| 1110 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR | 1097 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR |
| 1111 | 1098 |
| 1112 | |
| 1113 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 1099 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
| 1114 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 1100 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
| 1115 // that make_code_young doesn't do any garbage collection which allows us to | 1101 // that make_code_young doesn't do any garbage collection which allows us to |
| 1116 // save/restore the registers without worrying about which of them contain | 1102 // save/restore the registers without worrying about which of them contain |
| 1117 // pointers. | 1103 // pointers. |
| 1118 __ pushad(); | 1104 __ pushad(); |
| 1119 __ mov(eax, Operand(esp, 8 * kPointerSize)); | 1105 __ mov(eax, Operand(esp, 8 * kPointerSize)); |
| 1120 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); | 1106 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); |
| 1121 { // NOLINT | 1107 { // NOLINT |
| 1122 FrameScope scope(masm, StackFrame::MANUAL); | 1108 FrameScope scope(masm, StackFrame::MANUAL); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1135 __ push(ebp); // Caller's frame pointer. | 1121 __ push(ebp); // Caller's frame pointer. |
| 1136 __ mov(ebp, esp); | 1122 __ mov(ebp, esp); |
| 1137 __ push(esi); // Callee's context. | 1123 __ push(esi); // Callee's context. |
| 1138 __ push(edi); // Callee's JS Function. | 1124 __ push(edi); // Callee's JS Function. |
| 1139 __ push(eax); // Push return address after frame prologue. | 1125 __ push(eax); // Push return address after frame prologue. |
| 1140 | 1126 |
| 1141 // Jump to point after the code-age stub. | 1127 // Jump to point after the code-age stub. |
| 1142 __ ret(0); | 1128 __ ret(0); |
| 1143 } | 1129 } |
| 1144 | 1130 |
| 1145 | |
| 1146 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 1131 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
| 1147 GenerateMakeCodeYoungAgainCommon(masm); | 1132 GenerateMakeCodeYoungAgainCommon(masm); |
| 1148 } | 1133 } |
| 1149 | 1134 |
| 1150 | |
| 1151 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { | 1135 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { |
| 1152 Generate_MarkCodeAsExecutedOnce(masm); | 1136 Generate_MarkCodeAsExecutedOnce(masm); |
| 1153 } | 1137 } |
| 1154 | 1138 |
| 1155 | |
| 1156 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 1139 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
| 1157 SaveFPRegsMode save_doubles) { | 1140 SaveFPRegsMode save_doubles) { |
| 1158 // Enter an internal frame. | 1141 // Enter an internal frame. |
| 1159 { | 1142 { |
| 1160 FrameScope scope(masm, StackFrame::INTERNAL); | 1143 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1161 | 1144 |
| 1162 // Preserve registers across notification, this is important for compiled | 1145 // Preserve registers across notification, this is important for compiled |
| 1163 // stubs that tail call the runtime on deopts passing their parameters in | 1146 // stubs that tail call the runtime on deopts passing their parameters in |
| 1164 // registers. | 1147 // registers. |
| 1165 __ pushad(); | 1148 __ pushad(); |
| 1166 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); | 1149 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); |
| 1167 __ popad(); | 1150 __ popad(); |
| 1168 // Tear down internal frame. | 1151 // Tear down internal frame. |
| 1169 } | 1152 } |
| 1170 | 1153 |
| 1171 __ pop(MemOperand(esp, 0)); // Ignore state offset | 1154 __ pop(MemOperand(esp, 0)); // Ignore state offset |
| 1172 __ ret(0); // Return to IC Miss stub, continuation still on stack. | 1155 __ ret(0); // Return to IC Miss stub, continuation still on stack. |
| 1173 } | 1156 } |
| 1174 | 1157 |
| 1175 | |
| 1176 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 1158 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
| 1177 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 1159 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
| 1178 } | 1160 } |
| 1179 | 1161 |
| 1180 | |
| 1181 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 1162 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
| 1182 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 1163 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
| 1183 } | 1164 } |
| 1184 | 1165 |
| 1185 | |
| 1186 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 1166 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
| 1187 Deoptimizer::BailoutType type) { | 1167 Deoptimizer::BailoutType type) { |
| 1188 { | 1168 { |
| 1189 FrameScope scope(masm, StackFrame::INTERNAL); | 1169 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1190 | 1170 |
| 1191 // Pass deoptimization type to the runtime system. | 1171 // Pass deoptimization type to the runtime system. |
| 1192 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); | 1172 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); |
| 1193 __ CallRuntime(Runtime::kNotifyDeoptimized); | 1173 __ CallRuntime(Runtime::kNotifyDeoptimized); |
| 1194 | 1174 |
| 1195 // Tear down internal frame. | 1175 // Tear down internal frame. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1209 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); | 1189 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); |
| 1210 __ mov(eax, Operand(esp, 2 * kPointerSize)); | 1190 __ mov(eax, Operand(esp, 2 * kPointerSize)); |
| 1211 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)); | 1191 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)); |
| 1212 __ j(not_equal, ¬_tos_eax, Label::kNear); | 1192 __ j(not_equal, ¬_tos_eax, Label::kNear); |
| 1213 __ ret(2 * kPointerSize); // Remove state, eax. | 1193 __ ret(2 * kPointerSize); // Remove state, eax. |
| 1214 | 1194 |
| 1215 __ bind(¬_tos_eax); | 1195 __ bind(¬_tos_eax); |
| 1216 __ Abort(kNoCasesLeft); | 1196 __ Abort(kNoCasesLeft); |
| 1217 } | 1197 } |
| 1218 | 1198 |
| 1219 | |
| 1220 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 1199 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
| 1221 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | 1200 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); |
| 1222 } | 1201 } |
| 1223 | 1202 |
| 1224 | |
| 1225 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 1203 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
| 1226 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 1204 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
| 1227 } | 1205 } |
| 1228 | 1206 |
| 1229 | |
| 1230 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1207 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
| 1231 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 1208 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
| 1232 } | 1209 } |
| 1233 | 1210 |
| 1234 | |
| 1235 // static | 1211 // static |
| 1236 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, | 1212 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, |
| 1237 int field_index) { | 1213 int field_index) { |
| 1238 // ----------- S t a t e ------------- | 1214 // ----------- S t a t e ------------- |
| 1239 // -- eax : number of arguments | 1215 // -- eax : number of arguments |
| 1240 // -- edi : function | 1216 // -- edi : function |
| 1241 // -- esi : context | 1217 // -- esi : context |
| 1242 // -- esp[0] : return address | 1218 // -- esp[0] : return address |
| 1243 // -- esp[4] : receiver | 1219 // -- esp[4] : receiver |
| 1244 // ----------------------------------- | 1220 // ----------------------------------- |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 } | 1333 } |
| 1358 | 1334 |
| 1359 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1335 // 4c. The receiver is not callable, throw an appropriate TypeError. |
| 1360 __ bind(&receiver_not_callable); | 1336 __ bind(&receiver_not_callable); |
| 1361 { | 1337 { |
| 1362 __ mov(Operand(esp, kPointerSize), edi); | 1338 __ mov(Operand(esp, kPointerSize), edi); |
| 1363 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1339 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
| 1364 } | 1340 } |
| 1365 } | 1341 } |
| 1366 | 1342 |
| 1367 | |
| 1368 // static | 1343 // static |
| 1369 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { | 1344 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { |
| 1370 // Stack Layout: | 1345 // Stack Layout: |
| 1371 // esp[0] : Return address | 1346 // esp[0] : Return address |
| 1372 // esp[8] : Argument n | 1347 // esp[8] : Argument n |
| 1373 // esp[16] : Argument n-1 | 1348 // esp[16] : Argument n-1 |
| 1374 // ... | 1349 // ... |
| 1375 // esp[8 * n] : Argument 1 | 1350 // esp[8 * n] : Argument 1 |
| 1376 // esp[8 * (n + 1)] : Receiver (callable to call) | 1351 // esp[8 * (n + 1)] : Receiver (callable to call) |
| 1377 // | 1352 // |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1404 __ dec(ecx); | 1379 __ dec(ecx); |
| 1405 __ j(not_sign, &loop); // While non-negative (to copy return address). | 1380 __ j(not_sign, &loop); // While non-negative (to copy return address). |
| 1406 __ pop(ebx); // Discard copy of return address. | 1381 __ pop(ebx); // Discard copy of return address. |
| 1407 __ dec(eax); // One fewer argument (first argument is new receiver). | 1382 __ dec(eax); // One fewer argument (first argument is new receiver). |
| 1408 } | 1383 } |
| 1409 | 1384 |
| 1410 // 4. Call the callable. | 1385 // 4. Call the callable. |
| 1411 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1386 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1412 } | 1387 } |
| 1413 | 1388 |
| 1414 | |
| 1415 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1389 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
| 1416 // ----------- S t a t e ------------- | 1390 // ----------- S t a t e ------------- |
| 1417 // -- eax : argc | 1391 // -- eax : argc |
| 1418 // -- esp[0] : return address | 1392 // -- esp[0] : return address |
| 1419 // -- esp[4] : argumentsList | 1393 // -- esp[4] : argumentsList |
| 1420 // -- esp[8] : thisArgument | 1394 // -- esp[8] : thisArgument |
| 1421 // -- esp[12] : target | 1395 // -- esp[12] : target |
| 1422 // -- esp[16] : receiver | 1396 // -- esp[16] : receiver |
| 1423 // ----------------------------------- | 1397 // ----------------------------------- |
| 1424 | 1398 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 } | 1519 } |
| 1546 | 1520 |
| 1547 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1521 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
| 1548 __ bind(&new_target_not_constructor); | 1522 __ bind(&new_target_not_constructor); |
| 1549 { | 1523 { |
| 1550 __ mov(Operand(esp, kPointerSize), edx); | 1524 __ mov(Operand(esp, kPointerSize), edx); |
| 1551 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); | 1525 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
| 1552 } | 1526 } |
| 1553 } | 1527 } |
| 1554 | 1528 |
| 1555 | |
| 1556 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1529 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
| 1557 // ----------- S t a t e ------------- | 1530 // ----------- S t a t e ------------- |
| 1558 // -- eax : argc | 1531 // -- eax : argc |
| 1559 // -- esp[0] : return address | 1532 // -- esp[0] : return address |
| 1560 // -- esp[4] : last argument | 1533 // -- esp[4] : last argument |
| 1561 // ----------------------------------- | 1534 // ----------------------------------- |
| 1562 Label generic_array_code; | 1535 Label generic_array_code; |
| 1563 | 1536 |
| 1564 // Get the InternalArray function. | 1537 // Get the InternalArray function. |
| 1565 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); | 1538 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); |
| 1566 | 1539 |
| 1567 if (FLAG_debug_code) { | 1540 if (FLAG_debug_code) { |
| 1568 // Initial map for the builtin InternalArray function should be a map. | 1541 // Initial map for the builtin InternalArray function should be a map. |
| 1569 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 1542 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1570 // Will both indicate a NULL and a Smi. | 1543 // Will both indicate a NULL and a Smi. |
| 1571 __ test(ebx, Immediate(kSmiTagMask)); | 1544 __ test(ebx, Immediate(kSmiTagMask)); |
| 1572 __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction); | 1545 __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction); |
| 1573 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1546 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
| 1574 __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction); | 1547 __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction); |
| 1575 } | 1548 } |
| 1576 | 1549 |
| 1577 // Run the native code for the InternalArray function called as a normal | 1550 // Run the native code for the InternalArray function called as a normal |
| 1578 // function. | 1551 // function. |
| 1579 // tail call a stub | 1552 // tail call a stub |
| 1580 InternalArrayConstructorStub stub(masm->isolate()); | 1553 InternalArrayConstructorStub stub(masm->isolate()); |
| 1581 __ TailCallStub(&stub); | 1554 __ TailCallStub(&stub); |
| 1582 } | 1555 } |
| 1583 | 1556 |
| 1584 | |
| 1585 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 1557 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
| 1586 // ----------- S t a t e ------------- | 1558 // ----------- S t a t e ------------- |
| 1587 // -- eax : argc | 1559 // -- eax : argc |
| 1588 // -- esp[0] : return address | 1560 // -- esp[0] : return address |
| 1589 // -- esp[4] : last argument | 1561 // -- esp[4] : last argument |
| 1590 // ----------------------------------- | 1562 // ----------------------------------- |
| 1591 Label generic_array_code; | 1563 Label generic_array_code; |
| 1592 | 1564 |
| 1593 // Get the Array function. | 1565 // Get the Array function. |
| 1594 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); | 1566 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); |
| 1595 __ mov(edx, edi); | 1567 __ mov(edx, edi); |
| 1596 | 1568 |
| 1597 if (FLAG_debug_code) { | 1569 if (FLAG_debug_code) { |
| 1598 // Initial map for the builtin Array function should be a map. | 1570 // Initial map for the builtin Array function should be a map. |
| 1599 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 1571 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1600 // Will both indicate a NULL and a Smi. | 1572 // Will both indicate a NULL and a Smi. |
| 1601 __ test(ebx, Immediate(kSmiTagMask)); | 1573 __ test(ebx, Immediate(kSmiTagMask)); |
| 1602 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 1574 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
| 1603 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1575 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
| 1604 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 1576 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
| 1605 } | 1577 } |
| 1606 | 1578 |
| 1607 // Run the native code for the Array function called as a normal function. | 1579 // Run the native code for the Array function called as a normal function. |
| 1608 // tail call a stub | 1580 // tail call a stub |
| 1609 __ mov(ebx, masm->isolate()->factory()->undefined_value()); | 1581 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
| 1610 ArrayConstructorStub stub(masm->isolate()); | 1582 ArrayConstructorStub stub(masm->isolate()); |
| 1611 __ TailCallStub(&stub); | 1583 __ TailCallStub(&stub); |
| 1612 } | 1584 } |
| 1613 | 1585 |
| 1614 | |
| 1615 // static | 1586 // static |
| 1616 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { | 1587 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { |
| 1617 // ----------- S t a t e ------------- | 1588 // ----------- S t a t e ------------- |
| 1618 // -- eax : number of arguments | 1589 // -- eax : number of arguments |
| 1619 // -- edi : function | 1590 // -- edi : function |
| 1620 // -- esi : context | 1591 // -- esi : context |
| 1621 // -- esp[0] : return address | 1592 // -- esp[0] : return address |
| 1622 // -- esp[(argc - n) * 8] : arg[n] (zero-based) | 1593 // -- esp[(argc - n) * 8] : arg[n] (zero-based) |
| 1623 // -- esp[(argc + 1) * 8] : receiver | 1594 // -- esp[(argc + 1) * 8] : receiver |
| 1624 // ----------------------------------- | 1595 // ----------------------------------- |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1738 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
| 1768 __ PushReturnAddressFrom(ecx); | 1739 __ PushReturnAddressFrom(ecx); |
| 1769 __ Ret(); | 1740 __ Ret(); |
| 1770 } | 1741 } |
| 1771 | 1742 |
| 1772 // 2b. No arguments, return +0 (already in eax). | 1743 // 2b. No arguments, return +0 (already in eax). |
| 1773 __ bind(&no_arguments); | 1744 __ bind(&no_arguments); |
| 1774 __ ret(1 * kPointerSize); | 1745 __ ret(1 * kPointerSize); |
| 1775 } | 1746 } |
| 1776 | 1747 |
| 1777 | |
| 1778 // static | 1748 // static |
| 1779 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | 1749 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
| 1780 // ----------- S t a t e ------------- | 1750 // ----------- S t a t e ------------- |
| 1781 // -- eax : number of arguments | 1751 // -- eax : number of arguments |
| 1782 // -- edi : constructor function | 1752 // -- edi : constructor function |
| 1783 // -- edx : new target | 1753 // -- edx : new target |
| 1784 // -- esi : context | 1754 // -- esi : context |
| 1785 // -- esp[0] : return address | 1755 // -- esp[0] : return address |
| 1786 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1756 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1787 // -- esp[(argc + 1) * 4] : receiver | 1757 // -- esp[(argc + 1) * 4] : receiver |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 { | 1824 { |
| 1855 // Drop all arguments including the receiver. | 1825 // Drop all arguments including the receiver. |
| 1856 __ PopReturnAddressTo(esi); | 1826 __ PopReturnAddressTo(esi); |
| 1857 __ SmiUntag(ecx); | 1827 __ SmiUntag(ecx); |
| 1858 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize)); | 1828 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize)); |
| 1859 __ PushReturnAddressFrom(esi); | 1829 __ PushReturnAddressFrom(esi); |
| 1860 __ Ret(); | 1830 __ Ret(); |
| 1861 } | 1831 } |
| 1862 } | 1832 } |
| 1863 | 1833 |
| 1864 | |
| 1865 // static | 1834 // static |
| 1866 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1835 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 1867 // ----------- S t a t e ------------- | 1836 // ----------- S t a t e ------------- |
| 1868 // -- eax : number of arguments | 1837 // -- eax : number of arguments |
| 1869 // -- edi : constructor function | 1838 // -- edi : constructor function |
| 1870 // -- esi : context | 1839 // -- esi : context |
| 1871 // -- esp[0] : return address | 1840 // -- esp[0] : return address |
| 1872 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1841 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1873 // -- esp[(argc + 1) * 4] : receiver | 1842 // -- esp[(argc + 1) * 4] : receiver |
| 1874 // ----------------------------------- | 1843 // ----------------------------------- |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 __ bind(&drop_frame_and_ret); | 1896 __ bind(&drop_frame_and_ret); |
| 1928 { | 1897 { |
| 1929 // Drop all arguments including the receiver. | 1898 // Drop all arguments including the receiver. |
| 1930 __ PopReturnAddressTo(ecx); | 1899 __ PopReturnAddressTo(ecx); |
| 1931 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1900 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
| 1932 __ PushReturnAddressFrom(ecx); | 1901 __ PushReturnAddressFrom(ecx); |
| 1933 __ Ret(); | 1902 __ Ret(); |
| 1934 } | 1903 } |
| 1935 } | 1904 } |
| 1936 | 1905 |
| 1937 | |
| 1938 // static | 1906 // static |
| 1939 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1907 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
| 1940 // ----------- S t a t e ------------- | 1908 // ----------- S t a t e ------------- |
| 1941 // -- eax : number of arguments | 1909 // -- eax : number of arguments |
| 1942 // -- edi : constructor function | 1910 // -- edi : constructor function |
| 1943 // -- edx : new target | 1911 // -- edx : new target |
| 1944 // -- esi : context | 1912 // -- esi : context |
| 1945 // -- esp[0] : return address | 1913 // -- esp[0] : return address |
| 1946 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1914 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1947 // -- esp[(argc + 1) * 4] : receiver | 1915 // -- esp[(argc + 1) * 4] : receiver |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2021 __ bind(&drop_frame_and_ret); | 1989 __ bind(&drop_frame_and_ret); |
| 2022 { | 1990 { |
| 2023 // Drop all arguments including the receiver. | 1991 // Drop all arguments including the receiver. |
| 2024 __ PopReturnAddressTo(ecx); | 1992 __ PopReturnAddressTo(ecx); |
| 2025 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1993 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
| 2026 __ PushReturnAddressFrom(ecx); | 1994 __ PushReturnAddressFrom(ecx); |
| 2027 __ Ret(); | 1995 __ Ret(); |
| 2028 } | 1996 } |
| 2029 } | 1997 } |
| 2030 | 1998 |
| 2031 | |
| 2032 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1999 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
| 2033 Label* stack_overflow) { | 2000 Label* stack_overflow) { |
| 2034 // ----------- S t a t e ------------- | 2001 // ----------- S t a t e ------------- |
| 2035 // -- eax : actual number of arguments | 2002 // -- eax : actual number of arguments |
| 2036 // -- ebx : expected number of arguments | 2003 // -- ebx : expected number of arguments |
| 2037 // -- edx : new target (passed through to callee) | 2004 // -- edx : new target (passed through to callee) |
| 2038 // ----------------------------------- | 2005 // ----------------------------------- |
| 2039 // Check the stack for overflow. We are not trying to catch | 2006 // Check the stack for overflow. We are not trying to catch |
| 2040 // interruptions (e.g. debug break and preemption) here, so the "real stack | 2007 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 2041 // limit" is checked. | 2008 // limit" is checked. |
| 2042 ExternalReference real_stack_limit = | 2009 ExternalReference real_stack_limit = |
| 2043 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 2010 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
| 2044 __ mov(edi, Operand::StaticVariable(real_stack_limit)); | 2011 __ mov(edi, Operand::StaticVariable(real_stack_limit)); |
| 2045 // Make ecx the space we have left. The stack might already be overflowed | 2012 // Make ecx the space we have left. The stack might already be overflowed |
| 2046 // here which will cause ecx to become negative. | 2013 // here which will cause ecx to become negative. |
| 2047 __ mov(ecx, esp); | 2014 __ mov(ecx, esp); |
| 2048 __ sub(ecx, edi); | 2015 __ sub(ecx, edi); |
| 2049 // Make edi the space we need for the array when it is unrolled onto the | 2016 // Make edi the space we need for the array when it is unrolled onto the |
| 2050 // stack. | 2017 // stack. |
| 2051 __ mov(edi, ebx); | 2018 __ mov(edi, ebx); |
| 2052 __ shl(edi, kPointerSizeLog2); | 2019 __ shl(edi, kPointerSizeLog2); |
| 2053 // Check if the arguments will overflow the stack. | 2020 // Check if the arguments will overflow the stack. |
| 2054 __ cmp(ecx, edi); | 2021 __ cmp(ecx, edi); |
| 2055 __ j(less_equal, stack_overflow); // Signed comparison. | 2022 __ j(less_equal, stack_overflow); // Signed comparison. |
| 2056 } | 2023 } |
| 2057 | 2024 |
| 2058 | |
| 2059 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 2025 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
| 2060 __ push(ebp); | 2026 __ push(ebp); |
| 2061 __ mov(ebp, esp); | 2027 __ mov(ebp, esp); |
| 2062 | 2028 |
| 2063 // Store the arguments adaptor context sentinel. | 2029 // Store the arguments adaptor context sentinel. |
| 2064 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2030 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2065 | 2031 |
| 2066 // Push the function on the stack. | 2032 // Push the function on the stack. |
| 2067 __ push(edi); | 2033 __ push(edi); |
| 2068 | 2034 |
| 2069 // Preserve the number of arguments on the stack. Must preserve eax, | 2035 // Preserve the number of arguments on the stack. Must preserve eax, |
| 2070 // ebx and ecx because these registers are used when copying the | 2036 // ebx and ecx because these registers are used when copying the |
| 2071 // arguments and the receiver. | 2037 // arguments and the receiver. |
| 2072 STATIC_ASSERT(kSmiTagSize == 1); | 2038 STATIC_ASSERT(kSmiTagSize == 1); |
| 2073 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); | 2039 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); |
| 2074 __ push(edi); | 2040 __ push(edi); |
| 2075 } | 2041 } |
| 2076 | 2042 |
| 2077 | |
| 2078 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 2043 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
| 2079 // Retrieve the number of arguments from the stack. | 2044 // Retrieve the number of arguments from the stack. |
| 2080 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2045 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2081 | 2046 |
| 2082 // Leave the frame. | 2047 // Leave the frame. |
| 2083 __ leave(); | 2048 __ leave(); |
| 2084 | 2049 |
| 2085 // Remove caller arguments from the stack. | 2050 // Remove caller arguments from the stack. |
| 2086 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 2051 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 2087 __ pop(ecx); | 2052 __ pop(ecx); |
| 2088 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 2053 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
| 2089 __ push(ecx); | 2054 __ push(ecx); |
| 2090 } | 2055 } |
| 2091 | 2056 |
| 2092 | |
| 2093 // static | 2057 // static |
| 2094 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2058 void Builtins::Generate_Apply(MacroAssembler* masm) { |
| 2095 // ----------- S t a t e ------------- | 2059 // ----------- S t a t e ------------- |
| 2096 // -- eax : argumentsList | 2060 // -- eax : argumentsList |
| 2097 // -- edi : target | 2061 // -- edi : target |
| 2098 // -- edx : new.target (checked to be constructor or undefined) | 2062 // -- edx : new.target (checked to be constructor or undefined) |
| 2099 // -- esp[0] : return address. | 2063 // -- esp[0] : return address. |
| 2100 // -- esp[4] : thisArgument | 2064 // -- esp[4] : thisArgument |
| 2101 // ----------------------------------- | 2065 // ----------------------------------- |
| 2102 | 2066 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2417 CheckDebugStepCallWrapper()); | 2381 CheckDebugStepCallWrapper()); |
| 2418 // The function is a "classConstructor", need to raise an exception. | 2382 // The function is a "classConstructor", need to raise an exception. |
| 2419 __ bind(&class_constructor); | 2383 __ bind(&class_constructor); |
| 2420 { | 2384 { |
| 2421 FrameScope frame(masm, StackFrame::INTERNAL); | 2385 FrameScope frame(masm, StackFrame::INTERNAL); |
| 2422 __ push(edi); | 2386 __ push(edi); |
| 2423 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); | 2387 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); |
| 2424 } | 2388 } |
| 2425 } | 2389 } |
| 2426 | 2390 |
| 2427 | |
| 2428 namespace { | 2391 namespace { |
| 2429 | 2392 |
| 2430 void Generate_PushBoundArguments(MacroAssembler* masm) { | 2393 void Generate_PushBoundArguments(MacroAssembler* masm) { |
| 2431 // ----------- S t a t e ------------- | 2394 // ----------- S t a t e ------------- |
| 2432 // -- eax : the number of arguments (not including the receiver) | 2395 // -- eax : the number of arguments (not including the receiver) |
| 2433 // -- edx : new.target (only in case of [[Construct]]) | 2396 // -- edx : new.target (only in case of [[Construct]]) |
| 2434 // -- edi : target (checked to be a JSBoundFunction) | 2397 // -- edi : target (checked to be a JSBoundFunction) |
| 2435 // ----------------------------------- | 2398 // ----------------------------------- |
| 2436 | 2399 |
| 2437 // Load [[BoundArguments]] into ecx and length of that into ebx. | 2400 // Load [[BoundArguments]] into ecx and length of that into ebx. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2504 // Adjust effective number of arguments (eax contains the number of | 2467 // Adjust effective number of arguments (eax contains the number of |
| 2505 // arguments from the call plus return address plus the number of | 2468 // arguments from the call plus return address plus the number of |
| 2506 // [[BoundArguments]]), so we need to subtract one for the return address. | 2469 // [[BoundArguments]]), so we need to subtract one for the return address. |
| 2507 __ dec(eax); | 2470 __ dec(eax); |
| 2508 } | 2471 } |
| 2509 __ bind(&no_bound_arguments); | 2472 __ bind(&no_bound_arguments); |
| 2510 } | 2473 } |
| 2511 | 2474 |
| 2512 } // namespace | 2475 } // namespace |
| 2513 | 2476 |
| 2514 | |
| 2515 // static | 2477 // static |
| 2516 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, | 2478 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, |
| 2517 TailCallMode tail_call_mode) { | 2479 TailCallMode tail_call_mode) { |
| 2518 // ----------- S t a t e ------------- | 2480 // ----------- S t a t e ------------- |
| 2519 // -- eax : the number of arguments (not including the receiver) | 2481 // -- eax : the number of arguments (not including the receiver) |
| 2520 // -- edi : the function to call (checked to be a JSBoundFunction) | 2482 // -- edi : the function to call (checked to be a JSBoundFunction) |
| 2521 // ----------------------------------- | 2483 // ----------------------------------- |
| 2522 __ AssertBoundFunction(edi); | 2484 __ AssertBoundFunction(edi); |
| 2523 | 2485 |
| 2524 if (tail_call_mode == TailCallMode::kAllow) { | 2486 if (tail_call_mode == TailCallMode::kAllow) { |
| 2525 PrepareForTailCall(masm, eax, ebx, ecx, edx); | 2487 PrepareForTailCall(masm, eax, ebx, ecx, edx); |
| 2526 } | 2488 } |
| 2527 | 2489 |
| 2528 // Patch the receiver to [[BoundThis]]. | 2490 // Patch the receiver to [[BoundThis]]. |
| 2529 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset)); | 2491 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset)); |
| 2530 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx); | 2492 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx); |
| 2531 | 2493 |
| 2532 // Push the [[BoundArguments]] onto the stack. | 2494 // Push the [[BoundArguments]] onto the stack. |
| 2533 Generate_PushBoundArguments(masm); | 2495 Generate_PushBoundArguments(masm); |
| 2534 | 2496 |
| 2535 // Call the [[BoundTargetFunction]] via the Call builtin. | 2497 // Call the [[BoundTargetFunction]] via the Call builtin. |
| 2536 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2498 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2537 __ mov(ecx, Operand::StaticVariable(ExternalReference( | 2499 __ mov(ecx, Operand::StaticVariable(ExternalReference( |
| 2538 Builtins::kCall_ReceiverIsAny, masm->isolate()))); | 2500 Builtins::kCall_ReceiverIsAny, masm->isolate()))); |
| 2539 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2501 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
| 2540 __ jmp(ecx); | 2502 __ jmp(ecx); |
| 2541 } | 2503 } |
| 2542 | 2504 |
| 2543 | |
| 2544 // static | 2505 // static |
| 2545 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, | 2506 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, |
| 2546 TailCallMode tail_call_mode) { | 2507 TailCallMode tail_call_mode) { |
| 2547 // ----------- S t a t e ------------- | 2508 // ----------- S t a t e ------------- |
| 2548 // -- eax : the number of arguments (not including the receiver) | 2509 // -- eax : the number of arguments (not including the receiver) |
| 2549 // -- edi : the target to call (can be any Object). | 2510 // -- edi : the target to call (can be any Object). |
| 2550 // ----------------------------------- | 2511 // ----------------------------------- |
| 2551 | 2512 |
| 2552 Label non_callable, non_function, non_smi; | 2513 Label non_callable, non_function, non_smi; |
| 2553 __ JumpIfSmi(edi, &non_callable); | 2514 __ JumpIfSmi(edi, &non_callable); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2596 | 2557 |
| 2597 // 3. Call to something that is not callable. | 2558 // 3. Call to something that is not callable. |
| 2598 __ bind(&non_callable); | 2559 __ bind(&non_callable); |
| 2599 { | 2560 { |
| 2600 FrameScope scope(masm, StackFrame::INTERNAL); | 2561 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2601 __ Push(edi); | 2562 __ Push(edi); |
| 2602 __ CallRuntime(Runtime::kThrowCalledNonCallable); | 2563 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
| 2603 } | 2564 } |
| 2604 } | 2565 } |
| 2605 | 2566 |
| 2606 | |
| 2607 // static | 2567 // static |
| 2608 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2568 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 2609 // ----------- S t a t e ------------- | 2569 // ----------- S t a t e ------------- |
| 2610 // -- eax : the number of arguments (not including the receiver) | 2570 // -- eax : the number of arguments (not including the receiver) |
| 2611 // -- edx : the new target (checked to be a constructor) | 2571 // -- edx : the new target (checked to be a constructor) |
| 2612 // -- edi : the constructor to call (checked to be a JSFunction) | 2572 // -- edi : the constructor to call (checked to be a JSFunction) |
| 2613 // ----------------------------------- | 2573 // ----------------------------------- |
| 2614 __ AssertFunction(edi); | 2574 __ AssertFunction(edi); |
| 2615 | 2575 |
| 2616 // Calling convention for function specific ConstructStubs require | 2576 // Calling convention for function specific ConstructStubs require |
| 2617 // ebx to contain either an AllocationSite or undefined. | 2577 // ebx to contain either an AllocationSite or undefined. |
| 2618 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); | 2578 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); |
| 2619 | 2579 |
| 2620 // Tail call to the function-specific construct stub (still in the caller | 2580 // Tail call to the function-specific construct stub (still in the caller |
| 2621 // context at this point). | 2581 // context at this point). |
| 2622 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2582 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 2623 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); | 2583 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); |
| 2624 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2584 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
| 2625 __ jmp(ecx); | 2585 __ jmp(ecx); |
| 2626 } | 2586 } |
| 2627 | 2587 |
| 2628 | |
| 2629 // static | 2588 // static |
| 2630 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { | 2589 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
| 2631 // ----------- S t a t e ------------- | 2590 // ----------- S t a t e ------------- |
| 2632 // -- eax : the number of arguments (not including the receiver) | 2591 // -- eax : the number of arguments (not including the receiver) |
| 2633 // -- edx : the new target (checked to be a constructor) | 2592 // -- edx : the new target (checked to be a constructor) |
| 2634 // -- edi : the constructor to call (checked to be a JSBoundFunction) | 2593 // -- edi : the constructor to call (checked to be a JSBoundFunction) |
| 2635 // ----------------------------------- | 2594 // ----------------------------------- |
| 2636 __ AssertBoundFunction(edi); | 2595 __ AssertBoundFunction(edi); |
| 2637 | 2596 |
| 2638 // Push the [[BoundArguments]] onto the stack. | 2597 // Push the [[BoundArguments]] onto the stack. |
| 2639 Generate_PushBoundArguments(masm); | 2598 Generate_PushBoundArguments(masm); |
| 2640 | 2599 |
| 2641 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. | 2600 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
| 2642 { | 2601 { |
| 2643 Label done; | 2602 Label done; |
| 2644 __ cmp(edi, edx); | 2603 __ cmp(edi, edx); |
| 2645 __ j(not_equal, &done, Label::kNear); | 2604 __ j(not_equal, &done, Label::kNear); |
| 2646 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2605 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2647 __ bind(&done); | 2606 __ bind(&done); |
| 2648 } | 2607 } |
| 2649 | 2608 |
| 2650 // Construct the [[BoundTargetFunction]] via the Construct builtin. | 2609 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
| 2651 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2610 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2652 __ mov(ecx, Operand::StaticVariable( | 2611 __ mov(ecx, Operand::StaticVariable( |
| 2653 ExternalReference(Builtins::kConstruct, masm->isolate()))); | 2612 ExternalReference(Builtins::kConstruct, masm->isolate()))); |
| 2654 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2613 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
| 2655 __ jmp(ecx); | 2614 __ jmp(ecx); |
| 2656 } | 2615 } |
| 2657 | 2616 |
| 2658 | |
| 2659 // static | 2617 // static |
| 2660 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2618 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
| 2661 // ----------- S t a t e ------------- | 2619 // ----------- S t a t e ------------- |
| 2662 // -- eax : the number of arguments (not including the receiver) | 2620 // -- eax : the number of arguments (not including the receiver) |
| 2663 // -- edi : the constructor to call (checked to be a JSProxy) | 2621 // -- edi : the constructor to call (checked to be a JSProxy) |
| 2664 // -- edx : the new target (either the same as the constructor or | 2622 // -- edx : the new target (either the same as the constructor or |
| 2665 // the JSFunction on which new was invoked initially) | 2623 // the JSFunction on which new was invoked initially) |
| 2666 // ----------------------------------- | 2624 // ----------------------------------- |
| 2667 | 2625 |
| 2668 // Call into the Runtime for Proxy [[Construct]]. | 2626 // Call into the Runtime for Proxy [[Construct]]. |
| 2669 __ PopReturnAddressTo(ecx); | 2627 __ PopReturnAddressTo(ecx); |
| 2670 __ Push(edi); | 2628 __ Push(edi); |
| 2671 __ Push(edx); | 2629 __ Push(edx); |
| 2672 __ PushReturnAddressFrom(ecx); | 2630 __ PushReturnAddressFrom(ecx); |
| 2673 // Include the pushed new_target, constructor and the receiver. | 2631 // Include the pushed new_target, constructor and the receiver. |
| 2674 __ add(eax, Immediate(3)); | 2632 __ add(eax, Immediate(3)); |
| 2675 // Tail-call to the runtime. | 2633 // Tail-call to the runtime. |
| 2676 __ JumpToExternalReference( | 2634 __ JumpToExternalReference( |
| 2677 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); | 2635 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); |
| 2678 } | 2636 } |
| 2679 | 2637 |
| 2680 | |
| 2681 // static | 2638 // static |
| 2682 void Builtins::Generate_Construct(MacroAssembler* masm) { | 2639 void Builtins::Generate_Construct(MacroAssembler* masm) { |
| 2683 // ----------- S t a t e ------------- | 2640 // ----------- S t a t e ------------- |
| 2684 // -- eax : the number of arguments (not including the receiver) | 2641 // -- eax : the number of arguments (not including the receiver) |
| 2685 // -- edx : the new target (either the same as the constructor or | 2642 // -- edx : the new target (either the same as the constructor or |
| 2686 // the JSFunction on which new was invoked initially) | 2643 // the JSFunction on which new was invoked initially) |
| 2687 // -- edi : the constructor to call (can be any Object) | 2644 // -- edi : the constructor to call (can be any Object) |
| 2688 // ----------------------------------- | 2645 // ----------------------------------- |
| 2689 | 2646 |
| 2690 // Check if target is a Smi. | 2647 // Check if target is a Smi. |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2933 __ jmp(ecx); | 2890 __ jmp(ecx); |
| 2934 | 2891 |
| 2935 __ bind(&stack_overflow); | 2892 __ bind(&stack_overflow); |
| 2936 { | 2893 { |
| 2937 FrameScope frame(masm, StackFrame::MANUAL); | 2894 FrameScope frame(masm, StackFrame::MANUAL); |
| 2938 __ CallRuntime(Runtime::kThrowStackOverflow); | 2895 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 2939 __ int3(); | 2896 __ int3(); |
| 2940 } | 2897 } |
| 2941 } | 2898 } |
| 2942 | 2899 |
| 2943 | |
| 2944 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, | 2900 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
| 2945 Register function_template_info, | 2901 Register function_template_info, |
| 2946 Register scratch0, Register scratch1, | 2902 Register scratch0, Register scratch1, |
| 2947 Label* receiver_check_failed) { | 2903 Label* receiver_check_failed) { |
| 2948 // If there is no signature, return the holder. | 2904 // If there is no signature, return the holder. |
| 2949 __ CompareRoot(FieldOperand(function_template_info, | 2905 __ CompareRoot(FieldOperand(function_template_info, |
| 2950 FunctionTemplateInfo::kSignatureOffset), | 2906 FunctionTemplateInfo::kSignatureOffset), |
| 2951 Heap::kUndefinedValueRootIndex); | 2907 Heap::kUndefinedValueRootIndex); |
| 2952 Label receiver_check_passed; | 2908 Label receiver_check_passed; |
| 2953 __ j(equal, &receiver_check_passed, Label::kNear); | 2909 __ j(equal, &receiver_check_passed, Label::kNear); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2997 __ j(zero, receiver_check_failed); | 2953 __ j(zero, receiver_check_failed); |
| 2998 | 2954 |
| 2999 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); | 2955 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); |
| 3000 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 2956 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 3001 // Iterate. | 2957 // Iterate. |
| 3002 __ jmp(&prototype_loop_start, Label::kNear); | 2958 __ jmp(&prototype_loop_start, Label::kNear); |
| 3003 | 2959 |
| 3004 __ bind(&receiver_check_passed); | 2960 __ bind(&receiver_check_passed); |
| 3005 } | 2961 } |
| 3006 | 2962 |
| 3007 | |
| 3008 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { | 2963 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
| 3009 // ----------- S t a t e ------------- | 2964 // ----------- S t a t e ------------- |
| 3010 // -- eax : number of arguments (not including the receiver) | 2965 // -- eax : number of arguments (not including the receiver) |
| 3011 // -- edi : callee | 2966 // -- edi : callee |
| 3012 // -- esi : context | 2967 // -- esi : context |
| 3013 // -- esp[0] : return address | 2968 // -- esp[0] : return address |
| 3014 // -- esp[4] : last argument | 2969 // -- esp[4] : last argument |
| 3015 // -- ... | 2970 // -- ... |
| 3016 // -- esp[eax * 4] : first argument | 2971 // -- esp[eax * 4] : first argument |
| 3017 // -- esp[(eax + 1) * 4] : receiver | 2972 // -- esp[(eax + 1) * 4] : receiver |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3041 __ PopReturnAddressTo(ebx); | 2996 __ PopReturnAddressTo(ebx); |
| 3042 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); | 2997 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
| 3043 __ add(esp, eax); | 2998 __ add(esp, eax); |
| 3044 __ PushReturnAddressFrom(ebx); | 2999 __ PushReturnAddressFrom(ebx); |
| 3045 { | 3000 { |
| 3046 FrameScope scope(masm, StackFrame::INTERNAL); | 3001 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3047 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 3002 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
| 3048 } | 3003 } |
| 3049 } | 3004 } |
| 3050 | 3005 |
| 3051 | |
| 3052 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 3006 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 3053 // Lookup the function in the JavaScript frame. | 3007 // Lookup the function in the JavaScript frame. |
| 3054 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3008 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3055 { | 3009 { |
| 3056 FrameScope scope(masm, StackFrame::INTERNAL); | 3010 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3057 // Pass function as argument. | 3011 // Pass function as argument. |
| 3058 __ push(eax); | 3012 __ push(eax); |
| 3059 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 3013 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
| 3060 } | 3014 } |
| 3061 | 3015 |
| 3062 Label skip; | 3016 Label skip; |
| 3063 // If the code object is null, just return to the unoptimized code. | 3017 // If the code object is null, just return to the unoptimized code. |
| 3064 __ cmp(eax, Immediate(0)); | 3018 __ cmp(eax, Immediate(0)); |
| 3065 __ j(not_equal, &skip, Label::kNear); | 3019 __ j(not_equal, &skip, Label::kNear); |
| 3066 __ ret(0); | 3020 __ ret(0); |
| 3067 | 3021 |
| 3068 __ bind(&skip); | 3022 __ bind(&skip); |
| 3069 | 3023 |
| 3070 // Load deoptimization data from the code object. | 3024 // Load deoptimization data from the code object. |
| 3071 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3025 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
| 3072 | 3026 |
| 3073 // Load the OSR entrypoint offset from the deoptimization data. | 3027 // Load the OSR entrypoint offset from the deoptimization data. |
| 3074 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( | 3028 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( |
| 3075 DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag)); | 3029 DeoptimizationInputData::kOsrPcOffsetIndex) - |
| 3030 kHeapObjectTag)); |
| 3076 __ SmiUntag(ebx); | 3031 __ SmiUntag(ebx); |
| 3077 | 3032 |
| 3078 // Compute the target address = code_obj + header_size + osr_offset | 3033 // Compute the target address = code_obj + header_size + osr_offset |
| 3079 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3034 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
| 3080 | 3035 |
| 3081 // Overwrite the return address on the stack. | 3036 // Overwrite the return address on the stack. |
| 3082 __ mov(Operand(esp, 0), eax); | 3037 __ mov(Operand(esp, 0), eax); |
| 3083 | 3038 |
| 3084 // And "return" to the OSR entry point of the function. | 3039 // And "return" to the OSR entry point of the function. |
| 3085 __ ret(0); | 3040 __ ret(0); |
| 3086 } | 3041 } |
| 3087 | 3042 |
| 3088 | |
| 3089 #undef __ | 3043 #undef __ |
| 3090 } // namespace internal | 3044 } // namespace internal |
| 3091 } // namespace v8 | 3045 } // namespace v8 |
| 3092 | 3046 |
| 3093 #endif // V8_TARGET_ARCH_IA32 | 3047 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |