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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¬_seq_nor_cons); | 1560 __ bind(¬_seq_nor_cons); |
1561 // Compare flags are still set from (3). | 1561 // Compare flags are still set from (3). |
1562 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). | 1562 __ j(greater, ¬_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¬_string); | 3062 __ bind(¬_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, ¬_oddball, Label::kNear); | 3066 __ j(not_equal, ¬_oddball, Label::kNear); |
3068 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset)); | 3067 __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset)); |
3069 __ Ret(); | 3068 __ Ret(); |
3070 __ bind(¬_oddball); | 3069 __ bind(¬_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, ¬_smi, Label::kNear); | 3081 __ JumpIfNotSmi(eax, ¬_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(¬_smi); | 3088 __ bind(¬_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 Loading... |
3119 Label not_oddball; | 3118 Label not_oddball; |
3120 __ CmpInstanceType(edi, ODDBALL_TYPE); | 3119 __ CmpInstanceType(edi, ODDBALL_TYPE); |
3121 __ j(not_equal, ¬_oddball, Label::kNear); | 3120 __ j(not_equal, ¬_oddball, Label::kNear); |
3122 __ mov(eax, FieldOperand(eax, Oddball::kToStringOffset)); | 3121 __ mov(eax, FieldOperand(eax, Oddball::kToStringOffset)); |
3123 __ Ret(); | 3122 __ Ret(); |
3124 __ bind(¬_oddball); | 3123 __ bind(¬_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |