Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 1550923002: Remove uses of result size in TailCallRuntime and friends (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: change spaces Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 // and may not have contained the exponent value in the first place when the 610 // and may not have contained the exponent value in the first place when the
611 // exponent is a smi. We reset it with exponent value before bailing out. 611 // exponent is a smi. We reset it with exponent value before bailing out.
612 __ j(not_equal, &done); 612 __ j(not_equal, &done);
613 __ Cvtsi2sd(double_exponent, exponent); 613 __ Cvtsi2sd(double_exponent, exponent);
614 614
615 // Returning or bailing out. 615 // Returning or bailing out.
616 Counters* counters = isolate()->counters(); 616 Counters* counters = isolate()->counters();
617 if (exponent_type() == ON_STACK) { 617 if (exponent_type() == ON_STACK) {
618 // The arguments are still on the stack. 618 // The arguments are still on the stack.
619 __ bind(&call_runtime); 619 __ bind(&call_runtime);
620 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1); 620 __ TailCallRuntime(Runtime::kMathPowRT, 2);
621 621
622 // The stub is called from non-optimized code, which expects the result 622 // The stub is called from non-optimized code, which expects the result
623 // as heap number in exponent. 623 // as heap number in exponent.
624 __ bind(&done); 624 __ bind(&done);
625 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); 625 __ AllocateHeapNumber(eax, scratch, base, &call_runtime);
626 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result); 626 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result);
627 __ IncrementCounter(counters->math_pow(), 1); 627 __ IncrementCounter(counters->math_pow(), 1);
628 __ ret(2 * kPointerSize); 628 __ ret(2 * kPointerSize);
629 } else { 629 } else {
630 __ bind(&call_runtime); 630 __ bind(&call_runtime);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); 681 __ test(key, Immediate(kSmiTagMask | kSmiSignMask));
682 __ j(not_zero, &slow); 682 __ j(not_zero, &slow);
683 683
684 // Everything is fine, call runtime. 684 // Everything is fine, call runtime.
685 __ pop(scratch); 685 __ pop(scratch);
686 __ push(receiver); // receiver 686 __ push(receiver); // receiver
687 __ push(key); // key 687 __ push(key); // key
688 __ push(scratch); // return address 688 __ push(scratch); // return address
689 689
690 // Perform tail call to the entry. 690 // Perform tail call to the entry.
691 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1); 691 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2);
692 692
693 __ bind(&slow); 693 __ bind(&slow);
694 PropertyAccessCompiler::TailCallBuiltin( 694 PropertyAccessCompiler::TailCallBuiltin(
695 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); 695 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
696 } 696 }
697 697
698 698
699 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { 699 void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
700 // Return address is on the stack. 700 // Return address is on the stack.
701 Label miss; 701 Label miss;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 __ neg(edx); 780 __ neg(edx);
781 __ mov(eax, Operand(ebx, edx, times_2, kDisplacement)); 781 __ mov(eax, Operand(ebx, edx, times_2, kDisplacement));
782 __ ret(0); 782 __ ret(0);
783 783
784 // Slow-case: Handle non-smi or out-of-bounds access to arguments 784 // Slow-case: Handle non-smi or out-of-bounds access to arguments
785 // by calling the runtime system. 785 // by calling the runtime system.
786 __ bind(&slow); 786 __ bind(&slow);
787 __ pop(ebx); // Return address. 787 __ pop(ebx); // Return address.
788 __ push(edx); 788 __ push(edx);
789 __ push(ebx); 789 __ push(ebx);
790 __ TailCallRuntime(Runtime::kArguments, 1, 1); 790 __ TailCallRuntime(Runtime::kArguments, 1);
791 } 791 }
792 792
793 793
794 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { 794 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
795 // ecx : number of parameters (tagged) 795 // ecx : number of parameters (tagged)
796 // edx : parameters pointer 796 // edx : parameters pointer
797 // edi : function 797 // edi : function
798 // esp[0] : return address 798 // esp[0] : return address
799 799
800 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function())); 800 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
(...skipping 11 matching lines...) Expand all
812 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 812 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
813 __ lea(edx, 813 __ lea(edx,
814 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset)); 814 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
815 815
816 __ bind(&runtime); 816 __ bind(&runtime);
817 __ pop(eax); // Pop return address. 817 __ pop(eax); // Pop return address.
818 __ push(edi); // Push function. 818 __ push(edi); // Push function.
819 __ push(edx); // Push parameters pointer. 819 __ push(edx); // Push parameters pointer.
820 __ push(ecx); // Push parameter count. 820 __ push(ecx); // Push parameter count.
821 __ push(eax); // Push return address. 821 __ push(eax); // Push return address.
822 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 822 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3);
823 } 823 }
824 824
825 825
826 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { 826 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
827 // ecx : number of parameters (tagged) 827 // ecx : number of parameters (tagged)
828 // edx : parameters pointer 828 // edx : parameters pointer
829 // edi : function 829 // edi : function
830 // esp[0] : return address 830 // esp[0] : return address
831 831
832 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function())); 832 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 // Do the runtime call to allocate the arguments object. 1047 // Do the runtime call to allocate the arguments object.
1048 __ bind(&runtime); 1048 __ bind(&runtime);
1049 __ pop(eax); // Remove saved mapped parameter count. 1049 __ pop(eax); // Remove saved mapped parameter count.
1050 __ pop(edi); // Pop saved function. 1050 __ pop(edi); // Pop saved function.
1051 __ pop(eax); // Remove saved parameter count. 1051 __ pop(eax); // Remove saved parameter count.
1052 __ pop(eax); // Pop return address. 1052 __ pop(eax); // Pop return address.
1053 __ push(edi); // Push function. 1053 __ push(edi); // Push function.
1054 __ push(edx); // Push parameters pointer. 1054 __ push(edx); // Push parameters pointer.
1055 __ push(ecx); // Push parameter count. 1055 __ push(ecx); // Push parameter count.
1056 __ push(eax); // Push return address. 1056 __ push(eax); // Push return address.
1057 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 1057 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3);
1058 } 1058 }
1059 1059
1060 1060
1061 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 1061 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
1062 // ecx : number of parameters (tagged) 1062 // ecx : number of parameters (tagged)
1063 // edx : parameters pointer 1063 // edx : parameters pointer
1064 // edi : function 1064 // edi : function
1065 // esp[0] : return address 1065 // esp[0] : return address
1066 1066
1067 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function())); 1067 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 __ bind(&done); 1141 __ bind(&done);
1142 __ ret(0); 1142 __ ret(0);
1143 1143
1144 // Do the runtime call to allocate the arguments object. 1144 // Do the runtime call to allocate the arguments object.
1145 __ bind(&runtime); 1145 __ bind(&runtime);
1146 __ pop(eax); // Pop return address. 1146 __ pop(eax); // Pop return address.
1147 __ push(edi); // Push function. 1147 __ push(edi); // Push function.
1148 __ push(edx); // Push parameters pointer. 1148 __ push(edx); // Push parameters pointer.
1149 __ push(ecx); // Push parameter count. 1149 __ push(ecx); // Push parameter count.
1150 __ push(eax); // Push return address. 1150 __ push(eax); // Push return address.
1151 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 1151 __ TailCallRuntime(Runtime::kNewStrictArguments, 3);
1152 } 1152 }
1153 1153
1154 1154
1155 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { 1155 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
1156 // esp[0] : return address 1156 // esp[0] : return address
1157 // esp[4] : language mode 1157 // esp[4] : language mode
1158 // esp[8] : index of rest parameter 1158 // esp[8] : index of rest parameter
1159 // esp[12] : number of parameters 1159 // esp[12] : number of parameters
1160 // esp[16] : receiver displacement 1160 // esp[16] : receiver displacement
1161 1161
1162 // Check if the calling frame is an arguments adaptor frame. 1162 // Check if the calling frame is an arguments adaptor frame.
1163 Label runtime; 1163 Label runtime;
1164 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 1164 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1165 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 1165 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
1166 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1166 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1167 __ j(not_equal, &runtime); 1167 __ j(not_equal, &runtime);
1168 1168
1169 // Patch the arguments.length and the parameters pointer. 1169 // Patch the arguments.length and the parameters pointer.
1170 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1170 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
1171 __ mov(Operand(esp, 3 * kPointerSize), ecx); 1171 __ mov(Operand(esp, 3 * kPointerSize), ecx);
1172 __ lea(edx, 1172 __ lea(edx,
1173 Operand(edx, ecx, times_2, StandardFrameConstants::kCallerSPOffset)); 1173 Operand(edx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
1174 __ mov(Operand(esp, 4 * kPointerSize), edx); 1174 __ mov(Operand(esp, 4 * kPointerSize), edx);
1175 1175
1176 __ bind(&runtime); 1176 __ bind(&runtime);
1177 __ TailCallRuntime(Runtime::kNewRestParam, 4, 1); 1177 __ TailCallRuntime(Runtime::kNewRestParam, 4);
1178 } 1178 }
1179 1179
1180 1180
1181 void RegExpExecStub::Generate(MacroAssembler* masm) { 1181 void RegExpExecStub::Generate(MacroAssembler* masm) {
1182 // Just jump directly to runtime if native RegExp is not selected at compile 1182 // Just jump directly to runtime if native RegExp is not selected at compile
1183 // time or if regexp entry in generated code is turned off runtime switch or 1183 // time or if regexp entry in generated code is turned off runtime switch or
1184 // at compilation. 1184 // at compilation.
1185 #ifdef V8_INTERPRETED_REGEXP 1185 #ifdef V8_INTERPRETED_REGEXP
1186 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 1186 __ TailCallRuntime(Runtime::kRegExpExec, 4);
1187 #else // V8_INTERPRETED_REGEXP 1187 #else // V8_INTERPRETED_REGEXP
1188 1188
1189 // Stack frame on entry. 1189 // Stack frame on entry.
1190 // esp[0]: return address 1190 // esp[0]: return address
1191 // esp[4]: last_match_info (expected JSArray) 1191 // esp[4]: last_match_info (expected JSArray)
1192 // esp[8]: previous index 1192 // esp[8]: previous index
1193 // esp[12]: subject string 1193 // esp[12]: subject string
1194 // esp[16]: JSRegExp object 1194 // esp[16]: JSRegExp object
1195 1195
1196 static const int kLastMatchInfoOffset = 1 * kPointerSize; 1196 static const int kLastMatchInfoOffset = 1 * kPointerSize;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1454 // haven't created the exception yet. Handle that in the runtime system. 1454 // haven't created the exception yet. Handle that in the runtime system.
1455 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 1455 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
1456 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, 1456 ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
1457 isolate()); 1457 isolate());
1458 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); 1458 __ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
1459 __ mov(eax, Operand::StaticVariable(pending_exception)); 1459 __ mov(eax, Operand::StaticVariable(pending_exception));
1460 __ cmp(edx, eax); 1460 __ cmp(edx, eax);
1461 __ j(equal, &runtime); 1461 __ j(equal, &runtime);
1462 1462
1463 // For exception, throw the exception again. 1463 // For exception, throw the exception again.
1464 __ TailCallRuntime(Runtime::kRegExpExecReThrow, 4, 1); 1464 __ TailCallRuntime(Runtime::kRegExpExecReThrow, 4);
1465 1465
1466 __ bind(&failure); 1466 __ bind(&failure);
1467 // For failure to match, return null. 1467 // For failure to match, return null.
1468 __ mov(eax, factory->null_value()); 1468 __ mov(eax, factory->null_value());
1469 __ ret(4 * kPointerSize); 1469 __ ret(4 * kPointerSize);
1470 1470
1471 // Load RegExp data. 1471 // Load RegExp data.
1472 __ bind(&success); 1472 __ bind(&success);
1473 __ mov(eax, Operand(esp, kJSRegExpOffset)); 1473 __ mov(eax, Operand(esp, kJSRegExpOffset));
1474 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 1474 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 edi); 1546 edi);
1547 __ jmp(&next_capture); 1547 __ jmp(&next_capture);
1548 __ bind(&done); 1548 __ bind(&done);
1549 1549
1550 // Return last match info. 1550 // Return last match info.
1551 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); 1551 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
1552 __ ret(4 * kPointerSize); 1552 __ ret(4 * kPointerSize);
1553 1553
1554 // Do the runtime call to execute the regexp. 1554 // Do the runtime call to execute the regexp.
1555 __ bind(&runtime); 1555 __ bind(&runtime);
1556 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 1556 __ TailCallRuntime(Runtime::kRegExpExec, 4);
1557 1557
1558 // Deferred code for string handling. 1558 // Deferred code for string handling.
1559 // (7) Not a long external string? If yes, go to (10). 1559 // (7) Not a long external string? If yes, go to (10).
1560 __ bind(&not_seq_nor_cons); 1560 __ bind(&not_seq_nor_cons);
1561 // Compare flags are still set from (3). 1561 // Compare flags are still set from (3).
1562 __ j(greater, &not_long_external, Label::kNear); // Go to (10). 1562 __ j(greater, &not_long_external, Label::kNear); // Go to (10).
1563 1563
1564 // (8) External string. Short external strings have been ruled out. 1564 // (8) External string. Short external strings have been ruled out.
1565 __ bind(&external_string); 1565 __ bind(&external_string);
1566 // Reload instance type. 1566 // Reload instance type.
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 __ bind(&runtime_call); 1899 __ bind(&runtime_call);
1900 1900
1901 // Push arguments below the return address. 1901 // Push arguments below the return address.
1902 __ pop(ecx); 1902 __ pop(ecx);
1903 __ push(edx); 1903 __ push(edx);
1904 __ push(eax); 1904 __ push(eax);
1905 1905
1906 // Figure out which native to call and setup the arguments. 1906 // Figure out which native to call and setup the arguments.
1907 if (cc == equal) { 1907 if (cc == equal) {
1908 __ push(ecx); 1908 __ push(ecx);
1909 __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, 1909 __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2);
1910 1);
1911 } else { 1910 } else {
1912 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 1911 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
1913 1912
1914 // Restore return address on the stack. 1913 // Restore return address on the stack.
1915 __ push(ecx); 1914 __ push(ecx);
1916 1915
1917 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1916 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1918 // tagged as a small integer. 1917 // tagged as a small integer.
1919 __ TailCallRuntime( 1918 __ TailCallRuntime(
1920 is_strong(strength()) ? Runtime::kCompare_Strong : Runtime::kCompare, 3, 1919 is_strong(strength()) ? Runtime::kCompare_Strong : Runtime::kCompare,
1921 1); 1920 3);
1922 } 1921 }
1923 1922
1924 __ bind(&miss); 1923 __ bind(&miss);
1925 GenerateMiss(masm); 1924 GenerateMiss(masm);
1926 } 1925 }
1927 1926
1928 1927
1929 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { 1928 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
1930 // eax : number of arguments to the construct function 1929 // eax : number of arguments to the construct function
1931 // ebx : feedback vector 1930 // ebx : feedback vector
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
2608 2607
2609 // Found Proxy or access check needed: Call the runtime. 2608 // Found Proxy or access check needed: Call the runtime.
2610 __ bind(&fast_runtime_fallback); 2609 __ bind(&fast_runtime_fallback);
2611 __ PopReturnAddressTo(scratch); 2610 __ PopReturnAddressTo(scratch);
2612 __ Push(object); 2611 __ Push(object);
2613 __ Push(function_prototype); 2612 __ Push(function_prototype);
2614 __ PushReturnAddressFrom(scratch); 2613 __ PushReturnAddressFrom(scratch);
2615 // Invalidate the instanceof cache. 2614 // Invalidate the instanceof cache.
2616 __ Move(eax, Immediate(Smi::FromInt(0))); 2615 __ Move(eax, Immediate(Smi::FromInt(0)));
2617 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheFunctionRootIndex); 2616 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheFunctionRootIndex);
2618 __ TailCallRuntime(Runtime::kHasInPrototypeChain, 2, 1); 2617 __ TailCallRuntime(Runtime::kHasInPrototypeChain, 2);
2619 2618
2620 // Slow-case: Call the %InstanceOf runtime function. 2619 // Slow-case: Call the %InstanceOf runtime function.
2621 __ bind(&slow_case); 2620 __ bind(&slow_case);
2622 __ PopReturnAddressTo(scratch); 2621 __ PopReturnAddressTo(scratch);
2623 __ Push(object); 2622 __ Push(object);
2624 __ Push(function); 2623 __ Push(function);
2625 __ PushReturnAddressFrom(scratch); 2624 __ PushReturnAddressFrom(scratch);
2626 __ TailCallRuntime(Runtime::kInstanceOf, 2, 1); 2625 __ TailCallRuntime(Runtime::kInstanceOf, 2);
2627 } 2626 }
2628 2627
2629 2628
2630 // ------------------------------------------------------------------------- 2629 // -------------------------------------------------------------------------
2631 // StringCharCodeAtGenerator 2630 // StringCharCodeAtGenerator
2632 2631
2633 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2632 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2634 // If the receiver is a smi trigger the non-string case. 2633 // If the receiver is a smi trigger the non-string case.
2635 STATIC_ASSERT(kSmiTag == 0); 2634 STATIC_ASSERT(kSmiTag == 0);
2636 if (check_mode_ == RECEIVER_IS_UNKNOWN) { 2635 if (check_mode_ == RECEIVER_IS_UNKNOWN) {
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); 3006 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING);
3008 __ IncrementCounter(counters->sub_string_native(), 1); 3007 __ IncrementCounter(counters->sub_string_native(), 1);
3009 __ ret(3 * kPointerSize); 3008 __ ret(3 * kPointerSize);
3010 3009
3011 // Drop pushed values on the stack before tail call. 3010 // Drop pushed values on the stack before tail call.
3012 __ bind(&runtime_drop_two); 3011 __ bind(&runtime_drop_two);
3013 __ Drop(2); 3012 __ Drop(2);
3014 3013
3015 // Just jump to runtime to create the sub string. 3014 // Just jump to runtime to create the sub string.
3016 __ bind(&runtime); 3015 __ bind(&runtime);
3017 __ TailCallRuntime(Runtime::kSubString, 3, 1); 3016 __ TailCallRuntime(Runtime::kSubString, 3);
3018 3017
3019 __ bind(&single_char); 3018 __ bind(&single_char);
3020 // eax: string 3019 // eax: string
3021 // ebx: instance type 3020 // ebx: instance type
3022 // ecx: sub string length (smi) 3021 // ecx: sub string length (smi)
3023 // edx: from index (smi) 3022 // edx: from index (smi)
3024 StringCharAtGenerator generator(eax, edx, ecx, eax, &runtime, &runtime, 3023 StringCharAtGenerator generator(eax, edx, ecx, eax, &runtime, &runtime,
3025 &runtime, STRING_INDEX_IS_NUMBER, 3024 &runtime, STRING_INDEX_IS_NUMBER,
3026 RECEIVER_IS_STRING); 3025 RECEIVER_IS_STRING);
3027 generator.GenerateFast(masm); 3026 generator.GenerateFast(masm);
(...skipping 24 matching lines...) Expand all
3052 __ test(FieldOperand(eax, String::kHashFieldOffset), 3051 __ test(FieldOperand(eax, String::kHashFieldOffset),
3053 Immediate(String::kContainsCachedArrayIndexMask)); 3052 Immediate(String::kContainsCachedArrayIndexMask));
3054 __ j(not_zero, &slow_string, Label::kNear); 3053 __ j(not_zero, &slow_string, Label::kNear);
3055 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); 3054 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
3056 __ IndexFromHash(eax, eax); 3055 __ IndexFromHash(eax, eax);
3057 __ Ret(); 3056 __ Ret();
3058 __ bind(&slow_string); 3057 __ bind(&slow_string);
3059 __ pop(ecx); // Pop return address. 3058 __ pop(ecx); // Pop return address.
3060 __ push(eax); // Push argument. 3059 __ push(eax); // Push argument.
3061 __ push(ecx); // Push return address. 3060 __ push(ecx); // Push return address.
3062 __ TailCallRuntime(Runtime::kStringToNumber, 1, 1); 3061 __ TailCallRuntime(Runtime::kStringToNumber, 1);
3063 __ bind(&not_string); 3062 __ bind(&not_string);
3064 3063
3065 Label not_oddball; 3064 Label not_oddball;
3066 __ CmpInstanceType(edi, ODDBALL_TYPE); 3065 __ CmpInstanceType(edi, ODDBALL_TYPE);
3067 __ j(not_equal, &not_oddball, Label::kNear); 3066 __ j(not_equal, &not_oddball, Label::kNear);
3068 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset)); 3067 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
3069 __ Ret(); 3068 __ Ret();
3070 __ bind(&not_oddball); 3069 __ bind(&not_oddball);
3071 3070
3072 __ pop(ecx); // Pop return address. 3071 __ pop(ecx); // Pop return address.
3073 __ push(eax); // Push argument. 3072 __ push(eax); // Push argument.
3074 __ push(ecx); // Push return address. 3073 __ push(ecx); // Push return address.
3075 __ TailCallRuntime(Runtime::kToNumber, 1, 1); 3074 __ TailCallRuntime(Runtime::kToNumber, 1);
3076 } 3075 }
3077 3076
3078 3077
3079 void ToLengthStub::Generate(MacroAssembler* masm) { 3078 void ToLengthStub::Generate(MacroAssembler* masm) {
3080 // The ToLength stub takes on argument in eax. 3079 // The ToLength stub takes on argument in eax.
3081 Label not_smi, positive_smi; 3080 Label not_smi, positive_smi;
3082 __ JumpIfNotSmi(eax, &not_smi, Label::kNear); 3081 __ JumpIfNotSmi(eax, &not_smi, Label::kNear);
3083 STATIC_ASSERT(kSmiTag == 0); 3082 STATIC_ASSERT(kSmiTag == 0);
3084 __ test(eax, eax); 3083 __ test(eax, eax);
3085 __ j(greater_equal, &positive_smi, Label::kNear); 3084 __ j(greater_equal, &positive_smi, Label::kNear);
3086 __ xor_(eax, eax); 3085 __ xor_(eax, eax);
3087 __ bind(&positive_smi); 3086 __ bind(&positive_smi);
3088 __ Ret(); 3087 __ Ret();
3089 __ bind(&not_smi); 3088 __ bind(&not_smi);
3090 3089
3091 __ pop(ecx); // Pop return address. 3090 __ pop(ecx); // Pop return address.
3092 __ push(eax); // Push argument. 3091 __ push(eax); // Push argument.
3093 __ push(ecx); // Push return address. 3092 __ push(ecx); // Push return address.
3094 __ TailCallRuntime(Runtime::kToLength, 1, 1); 3093 __ TailCallRuntime(Runtime::kToLength, 1);
3095 } 3094 }
3096 3095
3097 3096
3098 void ToStringStub::Generate(MacroAssembler* masm) { 3097 void ToStringStub::Generate(MacroAssembler* masm) {
3099 // The ToString stub takes one argument in eax. 3098 // The ToString stub takes one argument in eax.
3100 Label is_number; 3099 Label is_number;
3101 __ JumpIfSmi(eax, &is_number, Label::kNear); 3100 __ JumpIfSmi(eax, &is_number, Label::kNear);
3102 3101
3103 Label not_string; 3102 Label not_string;
3104 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi); 3103 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi);
(...skipping 14 matching lines...) Expand all
3119 Label not_oddball; 3118 Label not_oddball;
3120 __ CmpInstanceType(edi, ODDBALL_TYPE); 3119 __ CmpInstanceType(edi, ODDBALL_TYPE);
3121 __ j(not_equal, &not_oddball, Label::kNear); 3120 __ j(not_equal, &not_oddball, Label::kNear);
3122 __ mov(eax, FieldOperand(eax, Oddball::kToStringOffset)); 3121 __ mov(eax, FieldOperand(eax, Oddball::kToStringOffset));
3123 __ Ret(); 3122 __ Ret();
3124 __ bind(&not_oddball); 3123 __ bind(&not_oddball);
3125 3124
3126 __ pop(ecx); // Pop return address. 3125 __ pop(ecx); // Pop return address.
3127 __ push(eax); // Push argument. 3126 __ push(eax); // Push argument.
3128 __ push(ecx); // Push return address. 3127 __ push(ecx); // Push return address.
3129 __ TailCallRuntime(Runtime::kToString, 1, 1); 3128 __ TailCallRuntime(Runtime::kToString, 1);
3130 } 3129 }
3131 3130
3132 3131
3133 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, 3132 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
3134 Register left, 3133 Register left,
3135 Register right, 3134 Register right,
3136 Register scratch1, 3135 Register scratch1,
3137 Register scratch2) { 3136 Register scratch2) {
3138 Register length = scratch1; 3137 Register length = scratch1;
3139 3138
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 StringHelper::GenerateCompareFlatOneByteStrings(masm, edx, eax, ecx, ebx, 3281 StringHelper::GenerateCompareFlatOneByteStrings(masm, edx, eax, ecx, ebx,
3283 edi); 3282 edi);
3284 3283
3285 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 3284 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
3286 // tagged as a small integer. 3285 // tagged as a small integer.
3287 __ bind(&runtime); 3286 __ bind(&runtime);
3288 __ PopReturnAddressTo(ecx); 3287 __ PopReturnAddressTo(ecx);
3289 __ Push(edx); 3288 __ Push(edx);
3290 __ Push(eax); 3289 __ Push(eax);
3291 __ PushReturnAddressFrom(ecx); 3290 __ PushReturnAddressFrom(ecx);
3292 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3291 __ TailCallRuntime(Runtime::kStringCompare, 2);
3293 } 3292 }
3294 3293
3295 3294
3296 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3295 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3297 // ----------- S t a t e ------------- 3296 // ----------- S t a t e -------------
3298 // -- edx : left 3297 // -- edx : left
3299 // -- eax : right 3298 // -- eax : right
3300 // -- esp[0] : return address 3299 // -- esp[0] : return address
3301 // ----------------------------------- 3300 // -----------------------------------
3302 3301
(...skipping 24 matching lines...) Expand all
3327 Label::Distance const miss_distance = 3326 Label::Distance const miss_distance =
3328 masm->emit_debug_code() ? Label::kFar : Label::kNear; 3327 masm->emit_debug_code() ? Label::kFar : Label::kNear;
3329 3328
3330 __ JumpIfSmi(edx, &miss, miss_distance); 3329 __ JumpIfSmi(edx, &miss, miss_distance);
3331 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 3330 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
3332 __ JumpIfSmi(eax, &miss, miss_distance); 3331 __ JumpIfSmi(eax, &miss, miss_distance);
3333 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3332 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
3334 __ JumpIfNotRoot(ecx, Heap::kBooleanMapRootIndex, &miss, miss_distance); 3333 __ JumpIfNotRoot(ecx, Heap::kBooleanMapRootIndex, &miss, miss_distance);
3335 __ JumpIfNotRoot(ebx, Heap::kBooleanMapRootIndex, &miss, miss_distance); 3334 __ JumpIfNotRoot(ebx, Heap::kBooleanMapRootIndex, &miss, miss_distance);
3336 if (op() != Token::EQ_STRICT && is_strong(strength())) { 3335 if (op() != Token::EQ_STRICT && is_strong(strength())) {
3337 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0, 1); 3336 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0);
3338 } else { 3337 } else {
3339 if (!Token::IsEqualityOp(op())) { 3338 if (!Token::IsEqualityOp(op())) {
3340 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset)); 3339 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
3341 __ AssertSmi(eax); 3340 __ AssertSmi(eax);
3342 __ mov(edx, FieldOperand(edx, Oddball::kToNumberOffset)); 3341 __ mov(edx, FieldOperand(edx, Oddball::kToNumberOffset));
3343 __ AssertSmi(edx); 3342 __ AssertSmi(edx);
3344 __ xchg(eax, edx); 3343 __ xchg(eax, edx);
3345 } 3344 }
3346 __ sub(eax, edx); 3345 __ sub(eax, edx);
3347 __ Ret(); 3346 __ Ret();
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3623 tmp2, tmp3); 3622 tmp2, tmp3);
3624 } 3623 }
3625 3624
3626 // Handle more complex cases in runtime. 3625 // Handle more complex cases in runtime.
3627 __ bind(&runtime); 3626 __ bind(&runtime);
3628 __ pop(tmp1); // Return address. 3627 __ pop(tmp1); // Return address.
3629 __ push(left); 3628 __ push(left);
3630 __ push(right); 3629 __ push(right);
3631 __ push(tmp1); 3630 __ push(tmp1);
3632 if (equality) { 3631 if (equality) {
3633 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); 3632 __ TailCallRuntime(Runtime::kStringEquals, 2);
3634 } else { 3633 } else {
3635 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3634 __ TailCallRuntime(Runtime::kStringCompare, 2);
3636 } 3635 }
3637 3636
3638 __ bind(&miss); 3637 __ bind(&miss);
3639 GenerateMiss(masm); 3638 GenerateMiss(masm);
3640 } 3639 }
3641 3640
3642 3641
3643 void CompareICStub::GenerateReceivers(MacroAssembler* masm) { 3642 void CompareICStub::GenerateReceivers(MacroAssembler* masm) {
3644 DCHECK_EQ(CompareICState::RECEIVER, state()); 3643 DCHECK_EQ(CompareICState::RECEIVER, state());
3645 Label miss; 3644 Label miss;
(...skipping 26 matching lines...) Expand all
3672 __ GetWeakValue(edi, cell); 3671 __ GetWeakValue(edi, cell);
3673 __ cmp(edi, FieldOperand(eax, HeapObject::kMapOffset)); 3672 __ cmp(edi, FieldOperand(eax, HeapObject::kMapOffset));
3674 __ j(not_equal, &miss, Label::kNear); 3673 __ j(not_equal, &miss, Label::kNear);
3675 __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset)); 3674 __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset));
3676 __ j(not_equal, &miss, Label::kNear); 3675 __ j(not_equal, &miss, Label::kNear);
3677 3676
3678 if (Token::IsEqualityOp(op())) { 3677 if (Token::IsEqualityOp(op())) {
3679 __ sub(eax, edx); 3678 __ sub(eax, edx);
3680 __ ret(0); 3679 __ ret(0);
3681 } else if (is_strong(strength())) { 3680 } else if (is_strong(strength())) {
3682 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0, 1); 3681 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0);
3683 } else { 3682 } else {
3684 __ PopReturnAddressTo(ecx); 3683 __ PopReturnAddressTo(ecx);
3685 __ Push(edx); 3684 __ Push(edx);
3686 __ Push(eax); 3685 __ Push(eax);
3687 __ Push(Immediate(Smi::FromInt(NegativeComparisonResult(GetCondition())))); 3686 __ Push(Immediate(Smi::FromInt(NegativeComparisonResult(GetCondition()))));
3688 __ PushReturnAddressFrom(ecx); 3687 __ PushReturnAddressFrom(ecx);
3689 __ TailCallRuntime(Runtime::kCompare, 3, 1); 3688 __ TailCallRuntime(Runtime::kCompare, 3);
3690 } 3689 }
3691 3690
3692 __ bind(&miss); 3691 __ bind(&miss);
3693 GenerateMiss(masm); 3692 GenerateMiss(masm);
3694 } 3693 }
3695 3694
3696 3695
3697 void CompareICStub::GenerateMiss(MacroAssembler* masm) { 3696 void CompareICStub::GenerateMiss(MacroAssembler* masm) {
3698 { 3697 {
3699 // Call the runtime system in a fresh internal frame. 3698 // Call the runtime system in a fresh internal frame.
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after
5151 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex); 5150 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex);
5152 __ j(equal, &slow_case, Label::kNear); 5151 __ j(equal, &slow_case, Label::kNear);
5153 __ Ret(); 5152 __ Ret();
5154 5153
5155 // Fallback to the runtime. 5154 // Fallback to the runtime.
5156 __ bind(&slow_case); 5155 __ bind(&slow_case);
5157 __ SmiTag(slot_reg); 5156 __ SmiTag(slot_reg);
5158 __ Pop(result_reg); // Pop return address. 5157 __ Pop(result_reg); // Pop return address.
5159 __ Push(slot_reg); 5158 __ Push(slot_reg);
5160 __ Push(result_reg); // Push return address. 5159 __ Push(result_reg); // Push return address.
5161 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1, 1); 5160 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1);
5162 } 5161 }
5163 5162
5164 5163
5165 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { 5164 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) {
5166 Register context_reg = esi; 5165 Register context_reg = esi;
5167 Register slot_reg = ebx; 5166 Register slot_reg = ebx;
5168 Register value_reg = eax; 5167 Register value_reg = eax;
5169 Register cell_reg = edi; 5168 Register cell_reg = edi;
5170 Register cell_details_reg = edx; 5169 Register cell_details_reg = edx;
5171 Register cell_value_reg = ecx; 5170 Register cell_value_reg = ecx;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
5275 // Fallback to the runtime. 5274 // Fallback to the runtime.
5276 __ bind(&slow_case); 5275 __ bind(&slow_case);
5277 __ SmiTag(slot_reg); 5276 __ SmiTag(slot_reg);
5278 __ Pop(cell_reg); // Pop return address. 5277 __ Pop(cell_reg); // Pop return address.
5279 __ Push(slot_reg); 5278 __ Push(slot_reg);
5280 __ Push(value_reg); 5279 __ Push(value_reg);
5281 __ Push(cell_reg); // Push return address. 5280 __ Push(cell_reg); // Push return address.
5282 __ TailCallRuntime(is_strict(language_mode()) 5281 __ TailCallRuntime(is_strict(language_mode())
5283 ? Runtime::kStoreGlobalViaContext_Strict 5282 ? Runtime::kStoreGlobalViaContext_Strict
5284 : Runtime::kStoreGlobalViaContext_Sloppy, 5283 : Runtime::kStoreGlobalViaContext_Sloppy,
5285 2, 1); 5284 2);
5286 } 5285 }
5287 5286
5288 5287
5289 // Generates an Operand for saving parameters after PrepareCallApiFunction. 5288 // Generates an Operand for saving parameters after PrepareCallApiFunction.
5290 static Operand ApiParameterOperand(int index) { 5289 static Operand ApiParameterOperand(int index) {
5291 return Operand(esp, index * kPointerSize); 5290 return Operand(esp, index * kPointerSize);
5292 } 5291 }
5293 5292
5294 5293
5295 // Prepares stack to put arguments (aligns and so on). Reserves 5294 // Prepares stack to put arguments (aligns and so on). Reserves
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
5446 DCHECK_EQ(0, stack_space); 5445 DCHECK_EQ(0, stack_space);
5447 __ pop(ecx); 5446 __ pop(ecx);
5448 __ add(esp, ebx); 5447 __ add(esp, ebx);
5449 __ jmp(ecx); 5448 __ jmp(ecx);
5450 } else { 5449 } else {
5451 __ ret(stack_space * kPointerSize); 5450 __ ret(stack_space * kPointerSize);
5452 } 5451 }
5453 5452
5454 // Re-throw by promoting a scheduled exception. 5453 // Re-throw by promoting a scheduled exception.
5455 __ bind(&promote_scheduled_exception); 5454 __ bind(&promote_scheduled_exception);
5456 __ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); 5455 __ TailCallRuntime(Runtime::kPromoteScheduledException, 0);
5457 5456
5458 // HandleScope limit has changed. Delete allocated extensions. 5457 // HandleScope limit has changed. Delete allocated extensions.
5459 ExternalReference delete_extensions = 5458 ExternalReference delete_extensions =
5460 ExternalReference::delete_handle_scope_extensions(isolate); 5459 ExternalReference::delete_handle_scope_extensions(isolate);
5461 __ bind(&delete_allocated_handles); 5460 __ bind(&delete_allocated_handles);
5462 __ mov(Operand::StaticVariable(limit_address), edi); 5461 __ mov(Operand::StaticVariable(limit_address), edi);
5463 __ mov(edi, eax); 5462 __ mov(edi, eax);
5464 __ mov(Operand(esp, 0), 5463 __ mov(Operand(esp, 0),
5465 Immediate(ExternalReference::isolate_address(isolate))); 5464 Immediate(ExternalReference::isolate_address(isolate)));
5466 __ mov(eax, Immediate(delete_extensions)); 5465 __ mov(eax, Immediate(delete_extensions));
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
5669 Operand(ebp, 7 * kPointerSize), NULL); 5668 Operand(ebp, 7 * kPointerSize), NULL);
5670 } 5669 }
5671 5670
5672 5671
5673 #undef __ 5672 #undef __
5674 5673
5675 } // namespace internal 5674 } // namespace internal
5676 } // namespace v8 5675 } // namespace v8
5677 5676
5678 #endif // V8_TARGET_ARCH_IA32 5677 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698