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

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

Issue 1553703002: [runtime] TailCallRuntime and CallRuntime should use default argument counts (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-12-29_TailCallRuntime_default_result_size_1_1550923002
Patch Set: 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
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); 620 __ TailCallRuntime(Runtime::kMathPowRT);
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); 691 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor);
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); 790 __ TailCallRuntime(Runtime::kArguments);
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); 822 __ TailCallRuntime(Runtime::kNewSloppyArguments);
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); 1057 __ TailCallRuntime(Runtime::kNewSloppyArguments);
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); 1151 __ TailCallRuntime(Runtime::kNewStrictArguments);
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); 1177 __ TailCallRuntime(Runtime::kNewRestParam);
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); 1186 __ TailCallRuntime(Runtime::kRegExpExec);
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); 1464 __ TailCallRuntime(Runtime::kRegExpExecReThrow);
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); 1556 __ TailCallRuntime(Runtime::kRegExpExec);
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);
1910 } else { 1910 } else {
1911 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); 1911 __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
1912 1912
1913 // Restore return address on the stack. 1913 // Restore return address on the stack.
1914 __ push(ecx); 1914 __ push(ecx);
1915 1915
1916 // 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)
1917 // tagged as a small integer. 1917 // tagged as a small integer.
1918 __ TailCallRuntime( 1918 __ TailCallRuntime(is_strong(strength()) ? Runtime::kCompare_Strong
1919 is_strong(strength()) ? Runtime::kCompare_Strong : Runtime::kCompare, 1919 : Runtime::kCompare);
1920 3);
1921 } 1920 }
1922 1921
1923 __ bind(&miss); 1922 __ bind(&miss);
1924 GenerateMiss(masm); 1923 GenerateMiss(masm);
1925 } 1924 }
1926 1925
1927 1926
1928 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { 1927 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
1929 // eax : number of arguments to the construct function 1928 // eax : number of arguments to the construct function
1930 // ebx : feedback vector 1929 // ebx : feedback vector
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 2241
2243 void CallICStub::GenerateMiss(MacroAssembler* masm) { 2242 void CallICStub::GenerateMiss(MacroAssembler* masm) {
2244 FrameScope scope(masm, StackFrame::INTERNAL); 2243 FrameScope scope(masm, StackFrame::INTERNAL);
2245 2244
2246 // Push the function and feedback info. 2245 // Push the function and feedback info.
2247 __ push(edi); 2246 __ push(edi);
2248 __ push(ebx); 2247 __ push(ebx);
2249 __ push(edx); 2248 __ push(edx);
2250 2249
2251 // Call the entry. 2250 // Call the entry.
2252 __ CallRuntime(Runtime::kCallIC_Miss, 3); 2251 __ CallRuntime(Runtime::kCallIC_Miss);
2253 2252
2254 // Move result to edi and exit the internal frame. 2253 // Move result to edi and exit the internal frame.
2255 __ mov(edi, eax); 2254 __ mov(edi, eax);
2256 } 2255 }
2257 2256
2258 2257
2259 bool CEntryStub::NeedsImmovableCode() { 2258 bool CEntryStub::NeedsImmovableCode() {
2260 return false; 2259 return false;
2261 } 2260 }
2262 2261
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 2606
2608 // Found Proxy or access check needed: Call the runtime. 2607 // Found Proxy or access check needed: Call the runtime.
2609 __ bind(&fast_runtime_fallback); 2608 __ bind(&fast_runtime_fallback);
2610 __ PopReturnAddressTo(scratch); 2609 __ PopReturnAddressTo(scratch);
2611 __ Push(object); 2610 __ Push(object);
2612 __ Push(function_prototype); 2611 __ Push(function_prototype);
2613 __ PushReturnAddressFrom(scratch); 2612 __ PushReturnAddressFrom(scratch);
2614 // Invalidate the instanceof cache. 2613 // Invalidate the instanceof cache.
2615 __ Move(eax, Immediate(Smi::FromInt(0))); 2614 __ Move(eax, Immediate(Smi::FromInt(0)));
2616 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheFunctionRootIndex); 2615 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheFunctionRootIndex);
2617 __ TailCallRuntime(Runtime::kHasInPrototypeChain, 2); 2616 __ TailCallRuntime(Runtime::kHasInPrototypeChain);
2618 2617
2619 // Slow-case: Call the %InstanceOf runtime function. 2618 // Slow-case: Call the %InstanceOf runtime function.
2620 __ bind(&slow_case); 2619 __ bind(&slow_case);
2621 __ PopReturnAddressTo(scratch); 2620 __ PopReturnAddressTo(scratch);
2622 __ Push(object); 2621 __ Push(object);
2623 __ Push(function); 2622 __ Push(function);
2624 __ PushReturnAddressFrom(scratch); 2623 __ PushReturnAddressFrom(scratch);
2625 __ TailCallRuntime(Runtime::kInstanceOf, 2); 2624 __ TailCallRuntime(Runtime::kInstanceOf);
2626 } 2625 }
2627 2626
2628 2627
2629 // ------------------------------------------------------------------------- 2628 // -------------------------------------------------------------------------
2630 // StringCharCodeAtGenerator 2629 // StringCharCodeAtGenerator
2631 2630
2632 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2631 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2633 // If the receiver is a smi trigger the non-string case. 2632 // If the receiver is a smi trigger the non-string case.
2634 STATIC_ASSERT(kSmiTag == 0); 2633 STATIC_ASSERT(kSmiTag == 0);
2635 if (check_mode_ == RECEIVER_IS_UNKNOWN) { 2634 if (check_mode_ == RECEIVER_IS_UNKNOWN) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 index_not_number_, 2675 index_not_number_,
2677 DONT_DO_SMI_CHECK); 2676 DONT_DO_SMI_CHECK);
2678 call_helper.BeforeCall(masm); 2677 call_helper.BeforeCall(masm);
2679 if (embed_mode == PART_OF_IC_HANDLER) { 2678 if (embed_mode == PART_OF_IC_HANDLER) {
2680 __ push(LoadWithVectorDescriptor::VectorRegister()); 2679 __ push(LoadWithVectorDescriptor::VectorRegister());
2681 __ push(LoadDescriptor::SlotRegister()); 2680 __ push(LoadDescriptor::SlotRegister());
2682 } 2681 }
2683 __ push(object_); 2682 __ push(object_);
2684 __ push(index_); // Consumed by runtime conversion function. 2683 __ push(index_); // Consumed by runtime conversion function.
2685 if (index_flags_ == STRING_INDEX_IS_NUMBER) { 2684 if (index_flags_ == STRING_INDEX_IS_NUMBER) {
2686 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); 2685 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero);
2687 } else { 2686 } else {
2688 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); 2687 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
2689 // NumberToSmi discards numbers that are not exact integers. 2688 // NumberToSmi discards numbers that are not exact integers.
2690 __ CallRuntime(Runtime::kNumberToSmi, 1); 2689 __ CallRuntime(Runtime::kNumberToSmi);
2691 } 2690 }
2692 if (!index_.is(eax)) { 2691 if (!index_.is(eax)) {
2693 // Save the conversion result before the pop instructions below 2692 // Save the conversion result before the pop instructions below
2694 // have a chance to overwrite it. 2693 // have a chance to overwrite it.
2695 __ mov(index_, eax); 2694 __ mov(index_, eax);
2696 } 2695 }
2697 __ pop(object_); 2696 __ pop(object_);
2698 if (embed_mode == PART_OF_IC_HANDLER) { 2697 if (embed_mode == PART_OF_IC_HANDLER) {
2699 __ pop(LoadDescriptor::SlotRegister()); 2698 __ pop(LoadDescriptor::SlotRegister());
2700 __ pop(LoadWithVectorDescriptor::VectorRegister()); 2699 __ pop(LoadWithVectorDescriptor::VectorRegister());
2701 } 2700 }
2702 // Reload the instance type. 2701 // Reload the instance type.
2703 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 2702 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
2704 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); 2703 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
2705 call_helper.AfterCall(masm); 2704 call_helper.AfterCall(masm);
2706 // If index is still not a smi, it must be out of range. 2705 // If index is still not a smi, it must be out of range.
2707 STATIC_ASSERT(kSmiTag == 0); 2706 STATIC_ASSERT(kSmiTag == 0);
2708 __ JumpIfNotSmi(index_, index_out_of_range_); 2707 __ JumpIfNotSmi(index_, index_out_of_range_);
2709 // Otherwise, return to the fast path. 2708 // Otherwise, return to the fast path.
2710 __ jmp(&got_smi_index_); 2709 __ jmp(&got_smi_index_);
2711 2710
2712 // Call runtime. We get here when the receiver is a string and the 2711 // Call runtime. We get here when the receiver is a string and the
2713 // index is a number, but the code of getting the actual character 2712 // index is a number, but the code of getting the actual character
2714 // is too complex (e.g., when the string needs to be flattened). 2713 // is too complex (e.g., when the string needs to be flattened).
2715 __ bind(&call_runtime_); 2714 __ bind(&call_runtime_);
2716 call_helper.BeforeCall(masm); 2715 call_helper.BeforeCall(masm);
2717 __ push(object_); 2716 __ push(object_);
2718 __ SmiTag(index_); 2717 __ SmiTag(index_);
2719 __ push(index_); 2718 __ push(index_);
2720 __ CallRuntime(Runtime::kStringCharCodeAtRT, 2); 2719 __ CallRuntime(Runtime::kStringCharCodeAtRT);
2721 if (!result_.is(eax)) { 2720 if (!result_.is(eax)) {
2722 __ mov(result_, eax); 2721 __ mov(result_, eax);
2723 } 2722 }
2724 call_helper.AfterCall(masm); 2723 call_helper.AfterCall(masm);
2725 __ jmp(&exit_); 2724 __ jmp(&exit_);
2726 2725
2727 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); 2726 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase);
2728 } 2727 }
2729 2728
2730 2729
(...skipping 25 matching lines...) Expand all
2756 2755
2757 2756
2758 void StringCharFromCodeGenerator::GenerateSlow( 2757 void StringCharFromCodeGenerator::GenerateSlow(
2759 MacroAssembler* masm, 2758 MacroAssembler* masm,
2760 const RuntimeCallHelper& call_helper) { 2759 const RuntimeCallHelper& call_helper) {
2761 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); 2760 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
2762 2761
2763 __ bind(&slow_case_); 2762 __ bind(&slow_case_);
2764 call_helper.BeforeCall(masm); 2763 call_helper.BeforeCall(masm);
2765 __ push(code_); 2764 __ push(code_);
2766 __ CallRuntime(Runtime::kStringCharFromCode, 1); 2765 __ CallRuntime(Runtime::kStringCharFromCode);
2767 if (!result_.is(eax)) { 2766 if (!result_.is(eax)) {
2768 __ mov(result_, eax); 2767 __ mov(result_, eax);
2769 } 2768 }
2770 call_helper.AfterCall(masm); 2769 call_helper.AfterCall(masm);
2771 __ jmp(&exit_); 2770 __ jmp(&exit_);
2772 2771
2773 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 2772 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
2774 } 2773 }
2775 2774
2776 2775
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
3006 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); 3005 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING);
3007 __ IncrementCounter(counters->sub_string_native(), 1); 3006 __ IncrementCounter(counters->sub_string_native(), 1);
3008 __ ret(3 * kPointerSize); 3007 __ ret(3 * kPointerSize);
3009 3008
3010 // Drop pushed values on the stack before tail call. 3009 // Drop pushed values on the stack before tail call.
3011 __ bind(&runtime_drop_two); 3010 __ bind(&runtime_drop_two);
3012 __ Drop(2); 3011 __ Drop(2);
3013 3012
3014 // Just jump to runtime to create the sub string. 3013 // Just jump to runtime to create the sub string.
3015 __ bind(&runtime); 3014 __ bind(&runtime);
3016 __ TailCallRuntime(Runtime::kSubString, 3); 3015 __ TailCallRuntime(Runtime::kSubString);
3017 3016
3018 __ bind(&single_char); 3017 __ bind(&single_char);
3019 // eax: string 3018 // eax: string
3020 // ebx: instance type 3019 // ebx: instance type
3021 // ecx: sub string length (smi) 3020 // ecx: sub string length (smi)
3022 // edx: from index (smi) 3021 // edx: from index (smi)
3023 StringCharAtGenerator generator(eax, edx, ecx, eax, &runtime, &runtime, 3022 StringCharAtGenerator generator(eax, edx, ecx, eax, &runtime, &runtime,
3024 &runtime, STRING_INDEX_IS_NUMBER, 3023 &runtime, STRING_INDEX_IS_NUMBER,
3025 RECEIVER_IS_STRING); 3024 RECEIVER_IS_STRING);
3026 generator.GenerateFast(masm); 3025 generator.GenerateFast(masm);
(...skipping 24 matching lines...) Expand all
3051 __ test(FieldOperand(eax, String::kHashFieldOffset), 3050 __ test(FieldOperand(eax, String::kHashFieldOffset),
3052 Immediate(String::kContainsCachedArrayIndexMask)); 3051 Immediate(String::kContainsCachedArrayIndexMask));
3053 __ j(not_zero, &slow_string, Label::kNear); 3052 __ j(not_zero, &slow_string, Label::kNear);
3054 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); 3053 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
3055 __ IndexFromHash(eax, eax); 3054 __ IndexFromHash(eax, eax);
3056 __ Ret(); 3055 __ Ret();
3057 __ bind(&slow_string); 3056 __ bind(&slow_string);
3058 __ pop(ecx); // Pop return address. 3057 __ pop(ecx); // Pop return address.
3059 __ push(eax); // Push argument. 3058 __ push(eax); // Push argument.
3060 __ push(ecx); // Push return address. 3059 __ push(ecx); // Push return address.
3061 __ TailCallRuntime(Runtime::kStringToNumber, 1); 3060 __ TailCallRuntime(Runtime::kStringToNumber);
3062 __ bind(&not_string); 3061 __ bind(&not_string);
3063 3062
3064 Label not_oddball; 3063 Label not_oddball;
3065 __ CmpInstanceType(edi, ODDBALL_TYPE); 3064 __ CmpInstanceType(edi, ODDBALL_TYPE);
3066 __ j(not_equal, &not_oddball, Label::kNear); 3065 __ j(not_equal, &not_oddball, Label::kNear);
3067 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset)); 3066 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
3068 __ Ret(); 3067 __ Ret();
3069 __ bind(&not_oddball); 3068 __ bind(&not_oddball);
3070 3069
3071 __ pop(ecx); // Pop return address. 3070 __ pop(ecx); // Pop return address.
3072 __ push(eax); // Push argument. 3071 __ push(eax); // Push argument.
3073 __ push(ecx); // Push return address. 3072 __ push(ecx); // Push return address.
3074 __ TailCallRuntime(Runtime::kToNumber, 1); 3073 __ TailCallRuntime(Runtime::kToNumber);
3075 } 3074 }
3076 3075
3077 3076
3078 void ToLengthStub::Generate(MacroAssembler* masm) { 3077 void ToLengthStub::Generate(MacroAssembler* masm) {
3079 // The ToLength stub takes on argument in eax. 3078 // The ToLength stub takes on argument in eax.
3080 Label not_smi, positive_smi; 3079 Label not_smi, positive_smi;
3081 __ JumpIfNotSmi(eax, &not_smi, Label::kNear); 3080 __ JumpIfNotSmi(eax, &not_smi, Label::kNear);
3082 STATIC_ASSERT(kSmiTag == 0); 3081 STATIC_ASSERT(kSmiTag == 0);
3083 __ test(eax, eax); 3082 __ test(eax, eax);
3084 __ j(greater_equal, &positive_smi, Label::kNear); 3083 __ j(greater_equal, &positive_smi, Label::kNear);
3085 __ xor_(eax, eax); 3084 __ xor_(eax, eax);
3086 __ bind(&positive_smi); 3085 __ bind(&positive_smi);
3087 __ Ret(); 3086 __ Ret();
3088 __ bind(&not_smi); 3087 __ bind(&not_smi);
3089 3088
3090 __ pop(ecx); // Pop return address. 3089 __ pop(ecx); // Pop return address.
3091 __ push(eax); // Push argument. 3090 __ push(eax); // Push argument.
3092 __ push(ecx); // Push return address. 3091 __ push(ecx); // Push return address.
3093 __ TailCallRuntime(Runtime::kToLength, 1); 3092 __ TailCallRuntime(Runtime::kToLength);
3094 } 3093 }
3095 3094
3096 3095
3097 void ToStringStub::Generate(MacroAssembler* masm) { 3096 void ToStringStub::Generate(MacroAssembler* masm) {
3098 // The ToString stub takes one argument in eax. 3097 // The ToString stub takes one argument in eax.
3099 Label is_number; 3098 Label is_number;
3100 __ JumpIfSmi(eax, &is_number, Label::kNear); 3099 __ JumpIfSmi(eax, &is_number, Label::kNear);
3101 3100
3102 Label not_string; 3101 Label not_string;
3103 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi); 3102 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi);
(...skipping 14 matching lines...) Expand all
3118 Label not_oddball; 3117 Label not_oddball;
3119 __ CmpInstanceType(edi, ODDBALL_TYPE); 3118 __ CmpInstanceType(edi, ODDBALL_TYPE);
3120 __ j(not_equal, &not_oddball, Label::kNear); 3119 __ j(not_equal, &not_oddball, Label::kNear);
3121 __ mov(eax, FieldOperand(eax, Oddball::kToStringOffset)); 3120 __ mov(eax, FieldOperand(eax, Oddball::kToStringOffset));
3122 __ Ret(); 3121 __ Ret();
3123 __ bind(&not_oddball); 3122 __ bind(&not_oddball);
3124 3123
3125 __ pop(ecx); // Pop return address. 3124 __ pop(ecx); // Pop return address.
3126 __ push(eax); // Push argument. 3125 __ push(eax); // Push argument.
3127 __ push(ecx); // Push return address. 3126 __ push(ecx); // Push return address.
3128 __ TailCallRuntime(Runtime::kToString, 1); 3127 __ TailCallRuntime(Runtime::kToString);
3129 } 3128 }
3130 3129
3131 3130
3132 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, 3131 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
3133 Register left, 3132 Register left,
3134 Register right, 3133 Register right,
3135 Register scratch1, 3134 Register scratch1,
3136 Register scratch2) { 3135 Register scratch2) {
3137 Register length = scratch1; 3136 Register length = scratch1;
3138 3137
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3281 StringHelper::GenerateCompareFlatOneByteStrings(masm, edx, eax, ecx, ebx, 3280 StringHelper::GenerateCompareFlatOneByteStrings(masm, edx, eax, ecx, ebx,
3282 edi); 3281 edi);
3283 3282
3284 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 3283 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
3285 // tagged as a small integer. 3284 // tagged as a small integer.
3286 __ bind(&runtime); 3285 __ bind(&runtime);
3287 __ PopReturnAddressTo(ecx); 3286 __ PopReturnAddressTo(ecx);
3288 __ Push(edx); 3287 __ Push(edx);
3289 __ Push(eax); 3288 __ Push(eax);
3290 __ PushReturnAddressFrom(ecx); 3289 __ PushReturnAddressFrom(ecx);
3291 __ TailCallRuntime(Runtime::kStringCompare, 2); 3290 __ TailCallRuntime(Runtime::kStringCompare);
3292 } 3291 }
3293 3292
3294 3293
3295 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3294 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3296 // ----------- S t a t e ------------- 3295 // ----------- S t a t e -------------
3297 // -- edx : left 3296 // -- edx : left
3298 // -- eax : right 3297 // -- eax : right
3299 // -- esp[0] : return address 3298 // -- esp[0] : return address
3300 // ----------------------------------- 3299 // -----------------------------------
3301 3300
(...skipping 24 matching lines...) Expand all
3326 Label::Distance const miss_distance = 3325 Label::Distance const miss_distance =
3327 masm->emit_debug_code() ? Label::kFar : Label::kNear; 3326 masm->emit_debug_code() ? Label::kFar : Label::kNear;
3328 3327
3329 __ JumpIfSmi(edx, &miss, miss_distance); 3328 __ JumpIfSmi(edx, &miss, miss_distance);
3330 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 3329 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
3331 __ JumpIfSmi(eax, &miss, miss_distance); 3330 __ JumpIfSmi(eax, &miss, miss_distance);
3332 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3331 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
3333 __ JumpIfNotRoot(ecx, Heap::kBooleanMapRootIndex, &miss, miss_distance); 3332 __ JumpIfNotRoot(ecx, Heap::kBooleanMapRootIndex, &miss, miss_distance);
3334 __ JumpIfNotRoot(ebx, Heap::kBooleanMapRootIndex, &miss, miss_distance); 3333 __ JumpIfNotRoot(ebx, Heap::kBooleanMapRootIndex, &miss, miss_distance);
3335 if (op() != Token::EQ_STRICT && is_strong(strength())) { 3334 if (op() != Token::EQ_STRICT && is_strong(strength())) {
3336 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0); 3335 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion);
3337 } else { 3336 } else {
3338 if (!Token::IsEqualityOp(op())) { 3337 if (!Token::IsEqualityOp(op())) {
3339 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset)); 3338 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
3340 __ AssertSmi(eax); 3339 __ AssertSmi(eax);
3341 __ mov(edx, FieldOperand(edx, Oddball::kToNumberOffset)); 3340 __ mov(edx, FieldOperand(edx, Oddball::kToNumberOffset));
3342 __ AssertSmi(edx); 3341 __ AssertSmi(edx);
3343 __ xchg(eax, edx); 3342 __ xchg(eax, edx);
3344 } 3343 }
3345 __ sub(eax, edx); 3344 __ sub(eax, edx);
3346 __ Ret(); 3345 __ Ret();
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3622 tmp2, tmp3); 3621 tmp2, tmp3);
3623 } 3622 }
3624 3623
3625 // Handle more complex cases in runtime. 3624 // Handle more complex cases in runtime.
3626 __ bind(&runtime); 3625 __ bind(&runtime);
3627 __ pop(tmp1); // Return address. 3626 __ pop(tmp1); // Return address.
3628 __ push(left); 3627 __ push(left);
3629 __ push(right); 3628 __ push(right);
3630 __ push(tmp1); 3629 __ push(tmp1);
3631 if (equality) { 3630 if (equality) {
3632 __ TailCallRuntime(Runtime::kStringEquals, 2); 3631 __ TailCallRuntime(Runtime::kStringEquals);
3633 } else { 3632 } else {
3634 __ TailCallRuntime(Runtime::kStringCompare, 2); 3633 __ TailCallRuntime(Runtime::kStringCompare);
3635 } 3634 }
3636 3635
3637 __ bind(&miss); 3636 __ bind(&miss);
3638 GenerateMiss(masm); 3637 GenerateMiss(masm);
3639 } 3638 }
3640 3639
3641 3640
3642 void CompareICStub::GenerateReceivers(MacroAssembler* masm) { 3641 void CompareICStub::GenerateReceivers(MacroAssembler* masm) {
3643 DCHECK_EQ(CompareICState::RECEIVER, state()); 3642 DCHECK_EQ(CompareICState::RECEIVER, state());
3644 Label miss; 3643 Label miss;
(...skipping 26 matching lines...) Expand all
3671 __ GetWeakValue(edi, cell); 3670 __ GetWeakValue(edi, cell);
3672 __ cmp(edi, FieldOperand(eax, HeapObject::kMapOffset)); 3671 __ cmp(edi, FieldOperand(eax, HeapObject::kMapOffset));
3673 __ j(not_equal, &miss, Label::kNear); 3672 __ j(not_equal, &miss, Label::kNear);
3674 __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset)); 3673 __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset));
3675 __ j(not_equal, &miss, Label::kNear); 3674 __ j(not_equal, &miss, Label::kNear);
3676 3675
3677 if (Token::IsEqualityOp(op())) { 3676 if (Token::IsEqualityOp(op())) {
3678 __ sub(eax, edx); 3677 __ sub(eax, edx);
3679 __ ret(0); 3678 __ ret(0);
3680 } else if (is_strong(strength())) { 3679 } else if (is_strong(strength())) {
3681 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0); 3680 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion);
3682 } else { 3681 } else {
3683 __ PopReturnAddressTo(ecx); 3682 __ PopReturnAddressTo(ecx);
3684 __ Push(edx); 3683 __ Push(edx);
3685 __ Push(eax); 3684 __ Push(eax);
3686 __ Push(Immediate(Smi::FromInt(NegativeComparisonResult(GetCondition())))); 3685 __ Push(Immediate(Smi::FromInt(NegativeComparisonResult(GetCondition()))));
3687 __ PushReturnAddressFrom(ecx); 3686 __ PushReturnAddressFrom(ecx);
3688 __ TailCallRuntime(Runtime::kCompare, 3); 3687 __ TailCallRuntime(Runtime::kCompare);
3689 } 3688 }
3690 3689
3691 __ bind(&miss); 3690 __ bind(&miss);
3692 GenerateMiss(masm); 3691 GenerateMiss(masm);
3693 } 3692 }
3694 3693
3695 3694
3696 void CompareICStub::GenerateMiss(MacroAssembler* masm) { 3695 void CompareICStub::GenerateMiss(MacroAssembler* masm) {
3697 { 3696 {
3698 // Call the runtime system in a fresh internal frame. 3697 // Call the runtime system in a fresh internal frame.
3699 FrameScope scope(masm, StackFrame::INTERNAL); 3698 FrameScope scope(masm, StackFrame::INTERNAL);
3700 __ push(edx); // Preserve edx and eax. 3699 __ push(edx); // Preserve edx and eax.
3701 __ push(eax); 3700 __ push(eax);
3702 __ push(edx); // And also use them as the arguments. 3701 __ push(edx); // And also use them as the arguments.
3703 __ push(eax); 3702 __ push(eax);
3704 __ push(Immediate(Smi::FromInt(op()))); 3703 __ push(Immediate(Smi::FromInt(op())));
3705 __ CallRuntime(Runtime::kCompareIC_Miss, 3); 3704 __ CallRuntime(Runtime::kCompareIC_Miss);
3706 // Compute the entry point of the rewritten stub. 3705 // Compute the entry point of the rewritten stub.
3707 __ lea(edi, FieldOperand(eax, Code::kHeaderSize)); 3706 __ lea(edi, FieldOperand(eax, Code::kHeaderSize));
3708 __ pop(eax); 3707 __ pop(eax);
3709 __ pop(edx); 3708 __ pop(edx);
3710 } 3709 }
3711 3710
3712 // Do a tail call to the rewritten stub. 3711 // Do a tail call to the rewritten stub.
3713 __ jmp(edi); 3712 __ jmp(edi);
3714 } 3713 }
3715 3714
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after
5150 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex); 5149 __ CompareRoot(result_reg, Heap::kTheHoleValueRootIndex);
5151 __ j(equal, &slow_case, Label::kNear); 5150 __ j(equal, &slow_case, Label::kNear);
5152 __ Ret(); 5151 __ Ret();
5153 5152
5154 // Fallback to the runtime. 5153 // Fallback to the runtime.
5155 __ bind(&slow_case); 5154 __ bind(&slow_case);
5156 __ SmiTag(slot_reg); 5155 __ SmiTag(slot_reg);
5157 __ Pop(result_reg); // Pop return address. 5156 __ Pop(result_reg); // Pop return address.
5158 __ Push(slot_reg); 5157 __ Push(slot_reg);
5159 __ Push(result_reg); // Push return address. 5158 __ Push(result_reg); // Push return address.
5160 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1); 5159 __ TailCallRuntime(Runtime::kLoadGlobalViaContext);
5161 } 5160 }
5162 5161
5163 5162
5164 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { 5163 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) {
5165 Register context_reg = esi; 5164 Register context_reg = esi;
5166 Register slot_reg = ebx; 5165 Register slot_reg = ebx;
5167 Register value_reg = eax; 5166 Register value_reg = eax;
5168 Register cell_reg = edi; 5167 Register cell_reg = edi;
5169 Register cell_details_reg = edx; 5168 Register cell_details_reg = edx;
5170 Register cell_value_reg = ecx; 5169 Register cell_value_reg = ecx;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
5273 5272
5274 // Fallback to the runtime. 5273 // Fallback to the runtime.
5275 __ bind(&slow_case); 5274 __ bind(&slow_case);
5276 __ SmiTag(slot_reg); 5275 __ SmiTag(slot_reg);
5277 __ Pop(cell_reg); // Pop return address. 5276 __ Pop(cell_reg); // Pop return address.
5278 __ Push(slot_reg); 5277 __ Push(slot_reg);
5279 __ Push(value_reg); 5278 __ Push(value_reg);
5280 __ Push(cell_reg); // Push return address. 5279 __ Push(cell_reg); // Push return address.
5281 __ TailCallRuntime(is_strict(language_mode()) 5280 __ TailCallRuntime(is_strict(language_mode())
5282 ? Runtime::kStoreGlobalViaContext_Strict 5281 ? Runtime::kStoreGlobalViaContext_Strict
5283 : Runtime::kStoreGlobalViaContext_Sloppy, 5282 : Runtime::kStoreGlobalViaContext_Sloppy);
5284 2);
5285 } 5283 }
5286 5284
5287 5285
5288 // Generates an Operand for saving parameters after PrepareCallApiFunction. 5286 // Generates an Operand for saving parameters after PrepareCallApiFunction.
5289 static Operand ApiParameterOperand(int index) { 5287 static Operand ApiParameterOperand(int index) {
5290 return Operand(esp, index * kPointerSize); 5288 return Operand(esp, index * kPointerSize);
5291 } 5289 }
5292 5290
5293 5291
5294 // Prepares stack to put arguments (aligns and so on). Reserves 5292 // Prepares stack to put arguments (aligns and so on). Reserves
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
5445 DCHECK_EQ(0, stack_space); 5443 DCHECK_EQ(0, stack_space);
5446 __ pop(ecx); 5444 __ pop(ecx);
5447 __ add(esp, ebx); 5445 __ add(esp, ebx);
5448 __ jmp(ecx); 5446 __ jmp(ecx);
5449 } else { 5447 } else {
5450 __ ret(stack_space * kPointerSize); 5448 __ ret(stack_space * kPointerSize);
5451 } 5449 }
5452 5450
5453 // Re-throw by promoting a scheduled exception. 5451 // Re-throw by promoting a scheduled exception.
5454 __ bind(&promote_scheduled_exception); 5452 __ bind(&promote_scheduled_exception);
5455 __ TailCallRuntime(Runtime::kPromoteScheduledException, 0); 5453 __ TailCallRuntime(Runtime::kPromoteScheduledException);
5456 5454
5457 // HandleScope limit has changed. Delete allocated extensions. 5455 // HandleScope limit has changed. Delete allocated extensions.
5458 ExternalReference delete_extensions = 5456 ExternalReference delete_extensions =
5459 ExternalReference::delete_handle_scope_extensions(isolate); 5457 ExternalReference::delete_handle_scope_extensions(isolate);
5460 __ bind(&delete_allocated_handles); 5458 __ bind(&delete_allocated_handles);
5461 __ mov(Operand::StaticVariable(limit_address), edi); 5459 __ mov(Operand::StaticVariable(limit_address), edi);
5462 __ mov(edi, eax); 5460 __ mov(edi, eax);
5463 __ mov(Operand(esp, 0), 5461 __ mov(Operand(esp, 0),
5464 Immediate(ExternalReference::isolate_address(isolate))); 5462 Immediate(ExternalReference::isolate_address(isolate)));
5465 __ mov(eax, Immediate(delete_extensions)); 5463 __ mov(eax, Immediate(delete_extensions));
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
5668 Operand(ebp, 7 * kPointerSize), NULL); 5666 Operand(ebp, 7 * kPointerSize), NULL);
5669 } 5667 }
5670 5668
5671 5669
5672 #undef __ 5670 #undef __
5673 5671
5674 } // namespace internal 5672 } // namespace internal
5675 } // namespace v8 5673 } // namespace v8
5676 5674
5677 #endif // V8_TARGET_ARCH_IA32 5675 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698