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 |