| 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" |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 __ push(ecx); | 442 __ push(ecx); |
| 443 __ ret(0); | 443 __ ret(0); |
| 444 } | 444 } |
| 445 | 445 |
| 446 | 446 |
| 447 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; | 447 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; |
| 448 | 448 |
| 449 | 449 |
| 450 // Clobbers ecx, edx, edi; preserves all other registers. | 450 // Clobbers ecx, edx, edi; preserves all other registers. |
| 451 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 451 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
| 452 const int calleeOffset, | |
| 453 IsTagged eax_is_tagged) { | 452 IsTagged eax_is_tagged) { |
| 454 // eax : the number of items to be pushed to the stack | 453 // eax : the number of items to be pushed to the stack |
| 455 // | 454 // |
| 456 // Check the stack for overflow. We are not trying to catch | 455 // Check the stack for overflow. We are not trying to catch |
| 457 // interruptions (e.g. debug break and preemption) here, so the "real stack | 456 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 458 // limit" is checked. | 457 // limit" is checked. |
| 459 Label okay; | 458 Label okay; |
| 460 ExternalReference real_stack_limit = | 459 ExternalReference real_stack_limit = |
| 461 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 460 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
| 462 __ mov(edi, Operand::StaticVariable(real_stack_limit)); | 461 __ mov(edi, Operand::StaticVariable(real_stack_limit)); |
| 463 // Make ecx the space we have left. The stack might already be overflowed | 462 // Make ecx the space we have left. The stack might already be overflowed |
| 464 // here which will cause ecx to become negative. | 463 // here which will cause ecx to become negative. |
| 465 __ mov(ecx, esp); | 464 __ mov(ecx, esp); |
| 466 __ sub(ecx, edi); | 465 __ sub(ecx, edi); |
| 467 // Make edx the space we need for the array when it is unrolled onto the | 466 // Make edx the space we need for the array when it is unrolled onto the |
| 468 // stack. | 467 // stack. |
| 469 __ mov(edx, eax); | 468 __ mov(edx, eax); |
| 470 int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0; | 469 int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0; |
| 471 __ shl(edx, kPointerSizeLog2 - smi_tag); | 470 __ shl(edx, kPointerSizeLog2 - smi_tag); |
| 472 // Check if the arguments will overflow the stack. | 471 // Check if the arguments will overflow the stack. |
| 473 __ cmp(ecx, edx); | 472 __ cmp(ecx, edx); |
| 474 __ j(greater, &okay); // Signed comparison. | 473 __ j(greater, &okay); // Signed comparison. |
| 475 | 474 |
| 476 // Out of stack space. | 475 // Out of stack space. |
| 477 __ push(Operand(ebp, calleeOffset)); // push this | |
| 478 if (eax_is_tagged == kEaxIsUntaggedInt) { | |
| 479 __ SmiTag(eax); | |
| 480 } | |
| 481 __ push(eax); | |
| 482 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 476 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 483 | 477 |
| 484 __ bind(&okay); | 478 __ bind(&okay); |
| 485 } | 479 } |
| 486 | 480 |
| 487 | 481 |
| 488 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 482 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
| 489 bool is_construct) { | 483 bool is_construct) { |
| 490 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 484 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 491 | 485 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 505 | 499 |
| 506 // Push the function and the receiver onto the stack. | 500 // Push the function and the receiver onto the stack. |
| 507 __ push(Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); | 501 __ push(Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); |
| 508 __ push(Operand(ebx, EntryFrameConstants::kReceiverArgOffset)); | 502 __ push(Operand(ebx, EntryFrameConstants::kReceiverArgOffset)); |
| 509 | 503 |
| 510 // Load the number of arguments and setup pointer to the arguments. | 504 // Load the number of arguments and setup pointer to the arguments. |
| 511 __ mov(eax, Operand(ebx, EntryFrameConstants::kArgcOffset)); | 505 __ mov(eax, Operand(ebx, EntryFrameConstants::kArgcOffset)); |
| 512 __ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset)); | 506 __ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset)); |
| 513 | 507 |
| 514 // Check if we have enough stack space to push all arguments. | 508 // Check if we have enough stack space to push all arguments. |
| 515 // The function is the first thing that was pushed above after entering | |
| 516 // the internal frame. | |
| 517 const int kFunctionOffset = | |
| 518 InternalFrameConstants::kCodeOffset - kPointerSize; | |
| 519 // Expects argument count in eax. Clobbers ecx, edx, edi. | 509 // Expects argument count in eax. Clobbers ecx, edx, edi. |
| 520 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsUntaggedInt); | 510 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); |
| 521 | 511 |
| 522 // Copy arguments to the stack in a loop. | 512 // Copy arguments to the stack in a loop. |
| 523 Label loop, entry; | 513 Label loop, entry; |
| 524 __ Move(ecx, Immediate(0)); | 514 __ Move(ecx, Immediate(0)); |
| 525 __ jmp(&entry, Label::kNear); | 515 __ jmp(&entry, Label::kNear); |
| 526 __ bind(&loop); | 516 __ bind(&loop); |
| 527 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv | 517 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv |
| 528 __ push(Operand(edx, 0)); // dereference handle | 518 __ push(Operand(edx, 0)); // dereference handle |
| 529 __ inc(ecx); | 519 __ inc(ecx); |
| 530 __ bind(&entry); | 520 __ bind(&entry); |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 | 1025 |
| 1036 __ push(Operand(ebp, kFunctionOffset)); // push this | 1026 __ push(Operand(ebp, kFunctionOffset)); // push this |
| 1037 __ push(Operand(ebp, kArgumentsOffset)); // push arguments | 1027 __ push(Operand(ebp, kArgumentsOffset)); // push arguments |
| 1038 if (targetIsArgument) { | 1028 if (targetIsArgument) { |
| 1039 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1029 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
| 1040 CALL_FUNCTION); | 1030 CALL_FUNCTION); |
| 1041 } else { | 1031 } else { |
| 1042 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1032 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
| 1043 } | 1033 } |
| 1044 | 1034 |
| 1045 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); | 1035 Generate_CheckStackOverflow(masm, kEaxIsSmiTagged); |
| 1046 | 1036 |
| 1047 // Push current index and limit. | 1037 // Push current index and limit. |
| 1048 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; | 1038 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
| 1049 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1039 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
| 1050 __ Push(eax); // limit | 1040 __ Push(eax); // limit |
| 1051 __ Push(Immediate(0)); // index | 1041 __ Push(Immediate(0)); // index |
| 1052 __ Push(Operand(ebp, kReceiverOffset)); // receiver | 1042 __ Push(Operand(ebp, kReceiverOffset)); // receiver |
| 1053 | 1043 |
| 1054 // Loop over the arguments array, pushing each value to the stack | 1044 // Loop over the arguments array, pushing each value to the stack |
| 1055 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, | 1045 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 __ mov(Operand(ebp, kNewTargetOffset), eax); | 1094 __ mov(Operand(ebp, kNewTargetOffset), eax); |
| 1105 | 1095 |
| 1106 // Validate arguments | 1096 // Validate arguments |
| 1107 __ bind(&validate_arguments); | 1097 __ bind(&validate_arguments); |
| 1108 __ push(Operand(ebp, kFunctionOffset)); | 1098 __ push(Operand(ebp, kFunctionOffset)); |
| 1109 __ push(Operand(ebp, kArgumentsOffset)); | 1099 __ push(Operand(ebp, kArgumentsOffset)); |
| 1110 __ push(Operand(ebp, kNewTargetOffset)); | 1100 __ push(Operand(ebp, kNewTargetOffset)); |
| 1111 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1101 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
| 1112 CALL_FUNCTION); | 1102 CALL_FUNCTION); |
| 1113 | 1103 |
| 1114 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); | 1104 Generate_CheckStackOverflow(masm, kEaxIsSmiTagged); |
| 1115 | 1105 |
| 1116 // Push current index and limit. | 1106 // Push current index and limit. |
| 1117 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; | 1107 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
| 1118 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1108 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
| 1119 __ Push(eax); // limit | 1109 __ Push(eax); // limit |
| 1120 __ push(Immediate(0)); // index | 1110 __ push(Immediate(0)); // index |
| 1121 // Push the constructor function as callee. | 1111 // Push the constructor function as callee. |
| 1122 __ push(Operand(ebp, kFunctionOffset)); | 1112 __ push(Operand(ebp, kFunctionOffset)); |
| 1123 | 1113 |
| 1124 // Loop over the arguments array, pushing each value to the stack | 1114 // Loop over the arguments array, pushing each value to the stack |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1837 | 1827 |
| 1838 __ bind(&ok); | 1828 __ bind(&ok); |
| 1839 __ ret(0); | 1829 __ ret(0); |
| 1840 } | 1830 } |
| 1841 | 1831 |
| 1842 #undef __ | 1832 #undef __ |
| 1843 } // namespace internal | 1833 } // namespace internal |
| 1844 } // namespace v8 | 1834 } // namespace v8 |
| 1845 | 1835 |
| 1846 #endif // V8_TARGET_ARCH_IA32 | 1836 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |