OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 Comment cmnt(masm_, "[ ToBoolean"); | 825 Comment cmnt(masm_, "[ ToBoolean"); |
826 | 826 |
827 // The value to convert should be popped from the frame. | 827 // The value to convert should be popped from the frame. |
828 Result value = frame_->Pop(); | 828 Result value = frame_->Pop(); |
829 value.ToRegister(); | 829 value.ToRegister(); |
830 | 830 |
831 if (value.is_integer32()) { // Also takes Smi case. | 831 if (value.is_integer32()) { // Also takes Smi case. |
832 Comment cmnt(masm_, "ONLY_INTEGER_32"); | 832 Comment cmnt(masm_, "ONLY_INTEGER_32"); |
833 if (FLAG_debug_code) { | 833 if (FLAG_debug_code) { |
834 Label ok; | 834 Label ok; |
835 __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number."); | 835 __ AbortIfNotNumber(value.reg()); |
836 __ test(value.reg(), Immediate(kSmiTagMask)); | 836 __ test(value.reg(), Immediate(kSmiTagMask)); |
837 __ j(zero, &ok); | 837 __ j(zero, &ok); |
838 __ fldz(); | 838 __ fldz(); |
839 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); | 839 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); |
840 __ FCmp(); | 840 __ FCmp(); |
841 __ j(not_zero, &ok); | 841 __ j(not_zero, &ok); |
842 __ Abort("Smi was wrapped in HeapNumber in output from bitop"); | 842 __ Abort("Smi was wrapped in HeapNumber in output from bitop"); |
843 __ bind(&ok); | 843 __ bind(&ok); |
844 } | 844 } |
845 // In the integer32 case there are no Smis hidden in heap numbers, so we | 845 // In the integer32 case there are no Smis hidden in heap numbers, so we |
846 // need only test for Smi zero. | 846 // need only test for Smi zero. |
847 __ test(value.reg(), Operand(value.reg())); | 847 __ test(value.reg(), Operand(value.reg())); |
848 dest->false_target()->Branch(zero); | 848 dest->false_target()->Branch(zero); |
849 value.Unuse(); | 849 value.Unuse(); |
850 dest->Split(not_zero); | 850 dest->Split(not_zero); |
851 } else if (value.is_number()) { | 851 } else if (value.is_number()) { |
852 Comment cmnt(masm_, "ONLY_NUMBER"); | 852 Comment cmnt(masm_, "ONLY_NUMBER"); |
853 // Fast case if NumberInfo indicates only numbers. | 853 // Fast case if NumberInfo indicates only numbers. |
854 if (FLAG_debug_code) { | 854 if (FLAG_debug_code) { |
855 __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number."); | 855 __ AbortIfNotNumber(value.reg()); |
856 } | 856 } |
857 // Smi => false iff zero. | 857 // Smi => false iff zero. |
858 ASSERT(kSmiTag == 0); | 858 ASSERT(kSmiTag == 0); |
859 __ test(value.reg(), Operand(value.reg())); | 859 __ test(value.reg(), Operand(value.reg())); |
860 dest->false_target()->Branch(zero); | 860 dest->false_target()->Branch(zero); |
861 __ test(value.reg(), Immediate(kSmiTagMask)); | 861 __ test(value.reg(), Immediate(kSmiTagMask)); |
862 dest->true_target()->Branch(zero); | 862 dest->true_target()->Branch(zero); |
863 __ fldz(); | 863 __ fldz(); |
864 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); | 864 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); |
865 __ FCmp(); | 865 __ FCmp(); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 Factory::heap_number_map()); | 1031 Factory::heap_number_map()); |
1032 __ j(not_equal, &call_runtime); | 1032 __ j(not_equal, &call_runtime); |
1033 } | 1033 } |
1034 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); | 1034 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); |
1035 if (mode_ == OVERWRITE_LEFT) { | 1035 if (mode_ == OVERWRITE_LEFT) { |
1036 __ mov(dst_, left_); | 1036 __ mov(dst_, left_); |
1037 } | 1037 } |
1038 __ jmp(&load_right); | 1038 __ jmp(&load_right); |
1039 | 1039 |
1040 __ bind(&left_smi); | 1040 __ bind(&left_smi); |
| 1041 } else { |
| 1042 if (FLAG_debug_code) __ AbortIfNotSmi(left_); |
1041 } | 1043 } |
1042 __ SmiUntag(left_); | 1044 __ SmiUntag(left_); |
1043 __ cvtsi2sd(xmm0, Operand(left_)); | 1045 __ cvtsi2sd(xmm0, Operand(left_)); |
1044 __ SmiTag(left_); | 1046 __ SmiTag(left_); |
1045 if (mode_ == OVERWRITE_LEFT) { | 1047 if (mode_ == OVERWRITE_LEFT) { |
1046 Label alloc_failure; | 1048 Label alloc_failure; |
1047 __ push(left_); | 1049 __ push(left_); |
1048 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 1050 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
1049 __ pop(left_); | 1051 __ pop(left_); |
1050 } | 1052 } |
(...skipping 12 matching lines...) Expand all Loading... |
1063 __ mov(dst_, right_); | 1065 __ mov(dst_, right_); |
1064 } else if (mode_ == NO_OVERWRITE) { | 1066 } else if (mode_ == NO_OVERWRITE) { |
1065 Label alloc_failure; | 1067 Label alloc_failure; |
1066 __ push(left_); | 1068 __ push(left_); |
1067 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 1069 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
1068 __ pop(left_); | 1070 __ pop(left_); |
1069 } | 1071 } |
1070 __ jmp(&do_op); | 1072 __ jmp(&do_op); |
1071 | 1073 |
1072 __ bind(&right_smi); | 1074 __ bind(&right_smi); |
| 1075 } else { |
| 1076 if (FLAG_debug_code) __ AbortIfNotSmi(right_); |
1073 } | 1077 } |
1074 __ SmiUntag(right_); | 1078 __ SmiUntag(right_); |
1075 __ cvtsi2sd(xmm1, Operand(right_)); | 1079 __ cvtsi2sd(xmm1, Operand(right_)); |
1076 __ SmiTag(right_); | 1080 __ SmiTag(right_); |
1077 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { | 1081 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { |
1078 Label alloc_failure; | 1082 Label alloc_failure; |
1079 __ push(left_); | 1083 __ push(left_); |
1080 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 1084 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
1081 __ pop(left_); | 1085 __ pop(left_); |
1082 } | 1086 } |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 DeferredInlineBinaryOperation* deferred = | 1572 DeferredInlineBinaryOperation* deferred = |
1569 new DeferredInlineBinaryOperation(op, | 1573 new DeferredInlineBinaryOperation(op, |
1570 answer.reg(), | 1574 answer.reg(), |
1571 left->reg(), | 1575 left->reg(), |
1572 ecx, | 1576 ecx, |
1573 left->number_info(), | 1577 left->number_info(), |
1574 right->number_info(), | 1578 right->number_info(), |
1575 overwrite_mode); | 1579 overwrite_mode); |
1576 | 1580 |
1577 Label do_op, left_nonsmi; | 1581 Label do_op, left_nonsmi; |
1578 // if right is a smi we make a fast case if left is either a smi | 1582 // If right is a smi we make a fast case if left is either a smi |
1579 // or a heapnumber. | 1583 // or a heapnumber. |
1580 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { | 1584 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { |
1581 CpuFeatures::Scope use_sse2(SSE2); | 1585 CpuFeatures::Scope use_sse2(SSE2); |
1582 __ mov(answer.reg(), left->reg()); | 1586 __ mov(answer.reg(), left->reg()); |
1583 // Fast case - both are actually smis. | 1587 // Fast case - both are actually smis. |
1584 if (!left->number_info().IsSmi()) { | 1588 if (!left->number_info().IsSmi()) { |
1585 __ test(answer.reg(), Immediate(kSmiTagMask)); | 1589 __ test(answer.reg(), Immediate(kSmiTagMask)); |
1586 __ j(not_zero, &left_nonsmi); | 1590 __ j(not_zero, &left_nonsmi); |
| 1591 } else { |
| 1592 if (FLAG_debug_code) __ AbortIfNotSmi(left->reg()); |
1587 } | 1593 } |
| 1594 if (FLAG_debug_code) __ AbortIfNotSmi(right->reg()); |
1588 __ SmiUntag(answer.reg()); | 1595 __ SmiUntag(answer.reg()); |
1589 __ jmp(&do_op); | 1596 __ jmp(&do_op); |
1590 | 1597 |
1591 __ bind(&left_nonsmi); | 1598 __ bind(&left_nonsmi); |
1592 // Branch if not a heapnumber. | 1599 // Branch if not a heapnumber. |
1593 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), | 1600 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), |
1594 Factory::heap_number_map()); | 1601 Factory::heap_number_map()); |
1595 deferred->Branch(not_equal); | 1602 deferred->Branch(not_equal); |
1596 | 1603 |
1597 // Load integer value into answer register using truncation. | 1604 // Load integer value into answer register using truncation. |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 deferred = new DeferredInlineSmiAdd(operand->reg(), | 2003 deferred = new DeferredInlineSmiAdd(operand->reg(), |
1997 operand->number_info(), | 2004 operand->number_info(), |
1998 smi_value, | 2005 smi_value, |
1999 overwrite_mode); | 2006 overwrite_mode); |
2000 } | 2007 } |
2001 __ add(Operand(operand->reg()), Immediate(value)); | 2008 __ add(Operand(operand->reg()), Immediate(value)); |
2002 deferred->Branch(overflow); | 2009 deferred->Branch(overflow); |
2003 if (!operand->number_info().IsSmi()) { | 2010 if (!operand->number_info().IsSmi()) { |
2004 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2011 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2005 deferred->Branch(not_zero); | 2012 deferred->Branch(not_zero); |
| 2013 } else { |
| 2014 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
2006 } | 2015 } |
2007 deferred->BindExit(); | 2016 deferred->BindExit(); |
2008 answer = *operand; | 2017 answer = *operand; |
2009 break; | 2018 break; |
2010 } | 2019 } |
2011 | 2020 |
2012 case Token::SUB: { | 2021 case Token::SUB: { |
2013 DeferredCode* deferred = NULL; | 2022 DeferredCode* deferred = NULL; |
2014 if (reversed) { | 2023 if (reversed) { |
2015 // The reversed case is only hit when the right operand is not a | 2024 // The reversed case is only hit when the right operand is not a |
(...skipping 17 matching lines...) Expand all Loading... |
2033 deferred = new DeferredInlineSmiSub(operand->reg(), | 2042 deferred = new DeferredInlineSmiSub(operand->reg(), |
2034 operand->number_info(), | 2043 operand->number_info(), |
2035 smi_value, | 2044 smi_value, |
2036 overwrite_mode); | 2045 overwrite_mode); |
2037 __ sub(Operand(operand->reg()), Immediate(value)); | 2046 __ sub(Operand(operand->reg()), Immediate(value)); |
2038 } | 2047 } |
2039 deferred->Branch(overflow); | 2048 deferred->Branch(overflow); |
2040 if (!operand->number_info().IsSmi()) { | 2049 if (!operand->number_info().IsSmi()) { |
2041 __ test(answer.reg(), Immediate(kSmiTagMask)); | 2050 __ test(answer.reg(), Immediate(kSmiTagMask)); |
2042 deferred->Branch(not_zero); | 2051 deferred->Branch(not_zero); |
| 2052 } else { |
| 2053 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
2043 } | 2054 } |
2044 deferred->BindExit(); | 2055 deferred->BindExit(); |
2045 operand->Unuse(); | 2056 operand->Unuse(); |
2046 break; | 2057 break; |
2047 } | 2058 } |
2048 | 2059 |
2049 case Token::SAR: | 2060 case Token::SAR: |
2050 if (reversed) { | 2061 if (reversed) { |
2051 Result constant_operand(value); | 2062 Result constant_operand(value); |
2052 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, | 2063 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
(...skipping 13 matching lines...) Expand all Loading... |
2066 smi_value, | 2077 smi_value, |
2067 overwrite_mode); | 2078 overwrite_mode); |
2068 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2079 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2069 deferred->Branch(not_zero); | 2080 deferred->Branch(not_zero); |
2070 if (shift_value > 0) { | 2081 if (shift_value > 0) { |
2071 __ sar(operand->reg(), shift_value); | 2082 __ sar(operand->reg(), shift_value); |
2072 __ and_(operand->reg(), ~kSmiTagMask); | 2083 __ and_(operand->reg(), ~kSmiTagMask); |
2073 } | 2084 } |
2074 deferred->BindExit(); | 2085 deferred->BindExit(); |
2075 } else { | 2086 } else { |
| 2087 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
2076 if (shift_value > 0) { | 2088 if (shift_value > 0) { |
2077 __ sar(operand->reg(), shift_value); | 2089 __ sar(operand->reg(), shift_value); |
2078 __ and_(operand->reg(), ~kSmiTagMask); | 2090 __ and_(operand->reg(), ~kSmiTagMask); |
2079 } | 2091 } |
2080 } | 2092 } |
2081 answer = *operand; | 2093 answer = *operand; |
2082 } | 2094 } |
2083 break; | 2095 break; |
2084 | 2096 |
2085 case Token::SHR: | 2097 case Token::SHR: |
(...skipping 11 matching lines...) Expand all Loading... |
2097 DeferredInlineSmiOperation* deferred = | 2109 DeferredInlineSmiOperation* deferred = |
2098 new DeferredInlineSmiOperation(op, | 2110 new DeferredInlineSmiOperation(op, |
2099 answer.reg(), | 2111 answer.reg(), |
2100 operand->reg(), | 2112 operand->reg(), |
2101 operand->number_info(), | 2113 operand->number_info(), |
2102 smi_value, | 2114 smi_value, |
2103 overwrite_mode); | 2115 overwrite_mode); |
2104 if (!operand->number_info().IsSmi()) { | 2116 if (!operand->number_info().IsSmi()) { |
2105 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2117 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2106 deferred->Branch(not_zero); | 2118 deferred->Branch(not_zero); |
| 2119 } else { |
| 2120 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
2107 } | 2121 } |
2108 __ mov(answer.reg(), operand->reg()); | 2122 __ mov(answer.reg(), operand->reg()); |
2109 __ SmiUntag(answer.reg()); | 2123 __ SmiUntag(answer.reg()); |
2110 __ shr(answer.reg(), shift_value); | 2124 __ shr(answer.reg(), shift_value); |
2111 // A negative Smi shifted right two is in the positive Smi range. | 2125 // A negative Smi shifted right two is in the positive Smi range. |
2112 if (shift_value < 2) { | 2126 if (shift_value < 2) { |
2113 __ test(answer.reg(), Immediate(0xc0000000)); | 2127 __ test(answer.reg(), Immediate(0xc0000000)); |
2114 deferred->Branch(not_zero); | 2128 deferred->Branch(not_zero); |
2115 } | 2129 } |
2116 operand->Unuse(); | 2130 operand->Unuse(); |
(...skipping 28 matching lines...) Expand all Loading... |
2145 new DeferredInlineSmiOperationReversed(op, | 2159 new DeferredInlineSmiOperationReversed(op, |
2146 answer.reg(), | 2160 answer.reg(), |
2147 smi_value, | 2161 smi_value, |
2148 right.reg(), | 2162 right.reg(), |
2149 right.number_info(), | 2163 right.number_info(), |
2150 overwrite_mode); | 2164 overwrite_mode); |
2151 __ mov(answer.reg(), Immediate(int_value)); | 2165 __ mov(answer.reg(), Immediate(int_value)); |
2152 __ sar(ecx, kSmiTagSize); | 2166 __ sar(ecx, kSmiTagSize); |
2153 if (!right.number_info().IsSmi()) { | 2167 if (!right.number_info().IsSmi()) { |
2154 deferred->Branch(carry); | 2168 deferred->Branch(carry); |
| 2169 } else { |
| 2170 if (FLAG_debug_code) __ AbortIfNotSmi(right.reg()); |
2155 } | 2171 } |
2156 __ shl_cl(answer.reg()); | 2172 __ shl_cl(answer.reg()); |
2157 __ cmp(answer.reg(), 0xc0000000); | 2173 __ cmp(answer.reg(), 0xc0000000); |
2158 deferred->Branch(sign); | 2174 deferred->Branch(sign); |
2159 __ SmiTag(answer.reg()); | 2175 __ SmiTag(answer.reg()); |
2160 | 2176 |
2161 deferred->BindExit(); | 2177 deferred->BindExit(); |
2162 } else { | 2178 } else { |
2163 // Only the least significant 5 bits of the shift value are used. | 2179 // Only the least significant 5 bits of the shift value are used. |
2164 // In the slow case, this masking is done inside the runtime call. | 2180 // In the slow case, this masking is done inside the runtime call. |
(...skipping 20 matching lines...) Expand all Loading... |
2185 DeferredInlineSmiOperation* deferred = | 2201 DeferredInlineSmiOperation* deferred = |
2186 new DeferredInlineSmiOperation(op, | 2202 new DeferredInlineSmiOperation(op, |
2187 answer.reg(), | 2203 answer.reg(), |
2188 operand->reg(), | 2204 operand->reg(), |
2189 operand->number_info(), | 2205 operand->number_info(), |
2190 smi_value, | 2206 smi_value, |
2191 overwrite_mode); | 2207 overwrite_mode); |
2192 if (!operand->number_info().IsSmi()) { | 2208 if (!operand->number_info().IsSmi()) { |
2193 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2209 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2194 deferred->Branch(not_zero); | 2210 deferred->Branch(not_zero); |
| 2211 } else { |
| 2212 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
2195 } | 2213 } |
2196 __ mov(answer.reg(), operand->reg()); | 2214 __ mov(answer.reg(), operand->reg()); |
2197 ASSERT(kSmiTag == 0); // adjust code if not the case | 2215 ASSERT(kSmiTag == 0); // adjust code if not the case |
2198 // We do no shifts, only the Smi conversion, if shift_value is 1. | 2216 // We do no shifts, only the Smi conversion, if shift_value is 1. |
2199 if (shift_value > 1) { | 2217 if (shift_value > 1) { |
2200 __ shl(answer.reg(), shift_value - 1); | 2218 __ shl(answer.reg(), shift_value - 1); |
2201 } | 2219 } |
2202 // Convert int result to Smi, checking that it is in int range. | 2220 // Convert int result to Smi, checking that it is in int range. |
2203 ASSERT(kSmiTagSize == 1); // adjust code if not the case | 2221 ASSERT(kSmiTagSize == 1); // adjust code if not the case |
2204 __ add(answer.reg(), Operand(answer.reg())); | 2222 __ add(answer.reg(), Operand(answer.reg())); |
(...skipping 22 matching lines...) Expand all Loading... |
2227 deferred = new DeferredInlineSmiOperation(op, | 2245 deferred = new DeferredInlineSmiOperation(op, |
2228 operand->reg(), | 2246 operand->reg(), |
2229 operand->reg(), | 2247 operand->reg(), |
2230 operand->number_info(), | 2248 operand->number_info(), |
2231 smi_value, | 2249 smi_value, |
2232 overwrite_mode); | 2250 overwrite_mode); |
2233 } | 2251 } |
2234 if (!operand->number_info().IsSmi()) { | 2252 if (!operand->number_info().IsSmi()) { |
2235 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2253 __ test(operand->reg(), Immediate(kSmiTagMask)); |
2236 deferred->Branch(not_zero); | 2254 deferred->Branch(not_zero); |
| 2255 } else { |
| 2256 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
2237 } | 2257 } |
2238 if (op == Token::BIT_AND) { | 2258 if (op == Token::BIT_AND) { |
2239 __ and_(Operand(operand->reg()), Immediate(value)); | 2259 __ and_(Operand(operand->reg()), Immediate(value)); |
2240 } else if (op == Token::BIT_XOR) { | 2260 } else if (op == Token::BIT_XOR) { |
2241 if (int_value != 0) { | 2261 if (int_value != 0) { |
2242 __ xor_(Operand(operand->reg()), Immediate(value)); | 2262 __ xor_(Operand(operand->reg()), Immediate(value)); |
2243 } | 2263 } |
2244 } else { | 2264 } else { |
2245 ASSERT(op == Token::BIT_OR); | 2265 ASSERT(op == Token::BIT_OR); |
2246 if (int_value != 0) { | 2266 if (int_value != 0) { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2420 Register left_reg = left_side.reg(); | 2440 Register left_reg = left_side.reg(); |
2421 Handle<Object> right_val = right_side.handle(); | 2441 Handle<Object> right_val = right_side.handle(); |
2422 | 2442 |
2423 // Here we split control flow to the stub call and inlined cases | 2443 // Here we split control flow to the stub call and inlined cases |
2424 // before finally splitting it to the control destination. We use | 2444 // before finally splitting it to the control destination. We use |
2425 // a jump target and branching to duplicate the virtual frame at | 2445 // a jump target and branching to duplicate the virtual frame at |
2426 // the first split. We manually handle the off-frame references | 2446 // the first split. We manually handle the off-frame references |
2427 // by reconstituting them on the non-fall-through path. | 2447 // by reconstituting them on the non-fall-through path. |
2428 | 2448 |
2429 if (left_side.is_smi()) { | 2449 if (left_side.is_smi()) { |
2430 if (FLAG_debug_code) { | 2450 if (FLAG_debug_code) __ AbortIfNotSmi(left_side.reg()); |
2431 __ AbortIfNotSmi(left_side.reg(), "Argument not a smi"); | |
2432 } | |
2433 } else { | 2451 } else { |
2434 JumpTarget is_smi; | 2452 JumpTarget is_smi; |
2435 __ test(left_side.reg(), Immediate(kSmiTagMask)); | 2453 __ test(left_side.reg(), Immediate(kSmiTagMask)); |
2436 is_smi.Branch(zero, taken); | 2454 is_smi.Branch(zero, taken); |
2437 | 2455 |
2438 bool is_for_loop_compare = (node->AsCompareOperation() != NULL) | 2456 bool is_for_loop_compare = (node->AsCompareOperation() != NULL) |
2439 && node->AsCompareOperation()->is_for_loop_condition(); | 2457 && node->AsCompareOperation()->is_for_loop_condition(); |
2440 if (!is_for_loop_compare | 2458 if (!is_for_loop_compare |
2441 && CpuFeatures::IsSupported(SSE2) | 2459 && CpuFeatures::IsSupported(SSE2) |
2442 && right_val->IsSmi()) { | 2460 && right_val->IsSmi()) { |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3733 | 3751 |
3734 if (node->is_fast_smi_loop()) { | 3752 if (node->is_fast_smi_loop()) { |
3735 // Set number type of the loop variable to smi. | 3753 // Set number type of the loop variable to smi. |
3736 Slot* slot = node->loop_variable()->slot(); | 3754 Slot* slot = node->loop_variable()->slot(); |
3737 ASSERT(slot->type() == Slot::LOCAL); | 3755 ASSERT(slot->type() == Slot::LOCAL); |
3738 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3756 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
3739 if (FLAG_debug_code) { | 3757 if (FLAG_debug_code) { |
3740 frame_->PushLocalAt(slot->index()); | 3758 frame_->PushLocalAt(slot->index()); |
3741 Result var = frame_->Pop(); | 3759 Result var = frame_->Pop(); |
3742 var.ToRegister(); | 3760 var.ToRegister(); |
3743 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3761 __ AbortIfNotSmi(var.reg()); |
3744 } | 3762 } |
3745 } | 3763 } |
3746 | 3764 |
3747 Visit(node->body()); | 3765 Visit(node->body()); |
3748 | 3766 |
3749 // If there is an update expression, compile it if necessary. | 3767 // If there is an update expression, compile it if necessary. |
3750 if (node->next() != NULL) { | 3768 if (node->next() != NULL) { |
3751 if (node->continue_target()->is_linked()) { | 3769 if (node->continue_target()->is_linked()) { |
3752 node->continue_target()->Bind(); | 3770 node->continue_target()->Bind(); |
3753 } | 3771 } |
(...skipping 13 matching lines...) Expand all Loading... |
3767 // set it to smi before compiling the test expression. | 3785 // set it to smi before compiling the test expression. |
3768 if (node->is_fast_smi_loop()) { | 3786 if (node->is_fast_smi_loop()) { |
3769 // Set number type of the loop variable to smi. | 3787 // Set number type of the loop variable to smi. |
3770 Slot* slot = node->loop_variable()->slot(); | 3788 Slot* slot = node->loop_variable()->slot(); |
3771 ASSERT(slot->type() == Slot::LOCAL); | 3789 ASSERT(slot->type() == Slot::LOCAL); |
3772 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3790 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
3773 if (FLAG_debug_code) { | 3791 if (FLAG_debug_code) { |
3774 frame_->PushLocalAt(slot->index()); | 3792 frame_->PushLocalAt(slot->index()); |
3775 Result var = frame_->Pop(); | 3793 Result var = frame_->Pop(); |
3776 var.ToRegister(); | 3794 var.ToRegister(); |
3777 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3795 __ AbortIfNotSmi(var.reg()); |
3778 } | 3796 } |
3779 } | 3797 } |
3780 | 3798 |
3781 // Based on the condition analysis, compile the backward jump as | 3799 // Based on the condition analysis, compile the backward jump as |
3782 // necessary. | 3800 // necessary. |
3783 switch (info) { | 3801 switch (info) { |
3784 case ALWAYS_TRUE: | 3802 case ALWAYS_TRUE: |
3785 if (has_valid_frame()) { | 3803 if (has_valid_frame()) { |
3786 if (node->next() == NULL) { | 3804 if (node->next() == NULL) { |
3787 node->continue_target()->Jump(); | 3805 node->continue_target()->Jump(); |
(...skipping 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6684 break; | 6702 break; |
6685 } | 6703 } |
6686 case Token::BIT_NOT: { | 6704 case Token::BIT_NOT: { |
6687 // Smi check. | 6705 // Smi check. |
6688 JumpTarget smi_label; | 6706 JumpTarget smi_label; |
6689 JumpTarget continue_label; | 6707 JumpTarget continue_label; |
6690 Result operand = frame_->Pop(); | 6708 Result operand = frame_->Pop(); |
6691 NumberInfo operand_info = operand.number_info(); | 6709 NumberInfo operand_info = operand.number_info(); |
6692 operand.ToRegister(); | 6710 operand.ToRegister(); |
6693 if (operand_info.IsSmi()) { | 6711 if (operand_info.IsSmi()) { |
6694 if (FLAG_debug_code) { | 6712 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg()); |
6695 __ AbortIfNotSmi(operand.reg(), "Operand not a smi."); | |
6696 } | |
6697 frame_->Spill(operand.reg()); | 6713 frame_->Spill(operand.reg()); |
6698 // Set smi tag bit. It will be reset by the not operation. | 6714 // Set smi tag bit. It will be reset by the not operation. |
6699 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); | 6715 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); |
6700 __ not_(operand.reg()); | 6716 __ not_(operand.reg()); |
6701 Result answer = operand; | 6717 Result answer = operand; |
6702 answer.set_number_info(NumberInfo::Smi()); | 6718 answer.set_number_info(NumberInfo::Smi()); |
6703 frame_->Push(&answer); | 6719 frame_->Push(&answer); |
6704 } else { | 6720 } else { |
6705 __ test(operand.reg(), Immediate(kSmiTagMask)); | 6721 __ test(operand.reg(), Immediate(kSmiTagMask)); |
6706 smi_label.Branch(zero, &operand, taken); | 6722 smi_label.Branch(zero, &operand, taken); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6886 // The old value that is return for postfix operations has the | 6902 // The old value that is return for postfix operations has the |
6887 // same type as the input value we got from the frame. | 6903 // same type as the input value we got from the frame. |
6888 old_value.set_number_info(new_value.number_info()); | 6904 old_value.set_number_info(new_value.number_info()); |
6889 } | 6905 } |
6890 | 6906 |
6891 // Ensure the new value is writable. | 6907 // Ensure the new value is writable. |
6892 frame_->Spill(new_value.reg()); | 6908 frame_->Spill(new_value.reg()); |
6893 | 6909 |
6894 Result tmp; | 6910 Result tmp; |
6895 if (new_value.is_smi()) { | 6911 if (new_value.is_smi()) { |
6896 if (FLAG_debug_code) { | 6912 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); |
6897 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi"); | |
6898 } | |
6899 } else { | 6913 } else { |
6900 // We don't know statically if the input is a smi. | 6914 // We don't know statically if the input is a smi. |
6901 // In order to combine the overflow and the smi tag check, we need | 6915 // In order to combine the overflow and the smi tag check, we need |
6902 // to be able to allocate a byte register. We attempt to do so | 6916 // to be able to allocate a byte register. We attempt to do so |
6903 // without spilling. If we fail, we will generate separate overflow | 6917 // without spilling. If we fail, we will generate separate overflow |
6904 // and smi tag checks. | 6918 // and smi tag checks. |
6905 // We allocate and clear a temporary byte register before performing | 6919 // We allocate and clear a temporary byte register before performing |
6906 // the count operation since clearing the register using xor will clear | 6920 // the count operation since clearing the register using xor will clear |
6907 // the overflow flag. | 6921 // the overflow flag. |
6908 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); | 6922 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); |
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7847 // Use masm-> here instead of the double underscore macro since extra | 7861 // Use masm-> here instead of the double underscore macro since extra |
7848 // coverage code can interfere with the patching. | 7862 // coverage code can interfere with the patching. |
7849 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 7863 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
7850 Immediate(Factory::null_value())); | 7864 Immediate(Factory::null_value())); |
7851 deferred->Branch(not_equal); | 7865 deferred->Branch(not_equal); |
7852 | 7866 |
7853 // Check that the key is a smi. | 7867 // Check that the key is a smi. |
7854 if (!key.is_smi()) { | 7868 if (!key.is_smi()) { |
7855 __ test(key.reg(), Immediate(kSmiTagMask)); | 7869 __ test(key.reg(), Immediate(kSmiTagMask)); |
7856 deferred->Branch(not_zero); | 7870 deferred->Branch(not_zero); |
| 7871 } else { |
| 7872 if (FLAG_debug_code) __ AbortIfNotSmi(key.reg()); |
7857 } | 7873 } |
7858 | 7874 |
7859 // Get the elements array from the receiver and check that it | 7875 // Get the elements array from the receiver and check that it |
7860 // is not a dictionary. | 7876 // is not a dictionary. |
7861 __ mov(elements.reg(), | 7877 __ mov(elements.reg(), |
7862 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 7878 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
7863 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), | 7879 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
7864 Immediate(Factory::fixed_array_map())); | 7880 Immediate(Factory::fixed_array_map())); |
7865 deferred->Branch(not_equal); | 7881 deferred->Branch(not_equal); |
7866 | 7882 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8000 | 8016 |
8001 | 8017 |
8002 static void CheckTwoForSminess(MacroAssembler* masm, | 8018 static void CheckTwoForSminess(MacroAssembler* masm, |
8003 Register left, Register right, Register scratch, | 8019 Register left, Register right, Register scratch, |
8004 NumberInfo left_info, NumberInfo right_info, | 8020 NumberInfo left_info, NumberInfo right_info, |
8005 DeferredInlineBinaryOperation* deferred) { | 8021 DeferredInlineBinaryOperation* deferred) { |
8006 if (left.is(right)) { | 8022 if (left.is(right)) { |
8007 if (!left_info.IsSmi()) { | 8023 if (!left_info.IsSmi()) { |
8008 __ test(left, Immediate(kSmiTagMask)); | 8024 __ test(left, Immediate(kSmiTagMask)); |
8009 deferred->Branch(not_zero); | 8025 deferred->Branch(not_zero); |
| 8026 } else { |
| 8027 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
8010 } | 8028 } |
8011 } else if (!left_info.IsSmi()) { | 8029 } else if (!left_info.IsSmi()) { |
8012 if (!right_info.IsSmi()) { | 8030 if (!right_info.IsSmi()) { |
8013 __ mov(scratch, left); | 8031 __ mov(scratch, left); |
8014 __ or_(scratch, Operand(right)); | 8032 __ or_(scratch, Operand(right)); |
8015 __ test(scratch, Immediate(kSmiTagMask)); | 8033 __ test(scratch, Immediate(kSmiTagMask)); |
8016 deferred->Branch(not_zero); | 8034 deferred->Branch(not_zero); |
8017 } else { | 8035 } else { |
8018 __ test(left, Immediate(kSmiTagMask)); | 8036 __ test(left, Immediate(kSmiTagMask)); |
8019 deferred->Branch(not_zero); | 8037 deferred->Branch(not_zero); |
| 8038 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
8020 } | 8039 } |
8021 } else { | 8040 } else { |
| 8041 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
8022 if (!right_info.IsSmi()) { | 8042 if (!right_info.IsSmi()) { |
8023 __ test(right, Immediate(kSmiTagMask)); | 8043 __ test(right, Immediate(kSmiTagMask)); |
8024 deferred->Branch(not_zero); | 8044 deferred->Branch(not_zero); |
| 8045 } else { |
| 8046 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
8025 } | 8047 } |
8026 } | 8048 } |
8027 } | 8049 } |
8028 | 8050 |
8029 | 8051 |
8030 Handle<String> Reference::GetName() { | 8052 Handle<String> Reference::GetName() { |
8031 ASSERT(type_ == NAMED); | 8053 ASSERT(type_ == NAMED); |
8032 Property* property = expression_->AsProperty(); | 8054 Property* property = expression_->AsProperty(); |
8033 if (property == NULL) { | 8055 if (property == NULL) { |
8034 // Global variable reference treated as a named property reference. | 8056 // Global variable reference treated as a named property reference. |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8521 __ mov(ebx, eax); | 8543 __ mov(ebx, eax); |
8522 __ mov(eax, edx); | 8544 __ mov(eax, edx); |
8523 } | 8545 } |
8524 } | 8546 } |
8525 if (!HasArgsInRegisters()) { | 8547 if (!HasArgsInRegisters()) { |
8526 __ mov(right, Operand(esp, 1 * kPointerSize)); | 8548 __ mov(right, Operand(esp, 1 * kPointerSize)); |
8527 __ mov(left, Operand(esp, 2 * kPointerSize)); | 8549 __ mov(left, Operand(esp, 2 * kPointerSize)); |
8528 } | 8550 } |
8529 | 8551 |
8530 if (static_operands_type_.IsSmi()) { | 8552 if (static_operands_type_.IsSmi()) { |
| 8553 if (FLAG_debug_code) { |
| 8554 __ AbortIfNotSmi(left); |
| 8555 __ AbortIfNotSmi(right); |
| 8556 } |
8531 if (op_ == Token::BIT_OR) { | 8557 if (op_ == Token::BIT_OR) { |
8532 __ or_(right, Operand(left)); | 8558 __ or_(right, Operand(left)); |
8533 GenerateReturn(masm); | 8559 GenerateReturn(masm); |
8534 return; | 8560 return; |
8535 } else if (op_ == Token::BIT_AND) { | 8561 } else if (op_ == Token::BIT_AND) { |
8536 __ and_(right, Operand(left)); | 8562 __ and_(right, Operand(left)); |
8537 GenerateReturn(masm); | 8563 GenerateReturn(masm); |
8538 return; | 8564 return; |
8539 } else if (op_ == Token::BIT_XOR) { | 8565 } else if (op_ == Token::BIT_XOR) { |
8540 __ xor_(right, Operand(left)); | 8566 __ xor_(right, Operand(left)); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8875 // forever for all other operations (also if smi code is skipped). | 8901 // forever for all other operations (also if smi code is skipped). |
8876 GenerateTypeTransition(masm); | 8902 GenerateTypeTransition(masm); |
8877 } | 8903 } |
8878 | 8904 |
8879 Label not_floats; | 8905 Label not_floats; |
8880 if (CpuFeatures::IsSupported(SSE2)) { | 8906 if (CpuFeatures::IsSupported(SSE2)) { |
8881 CpuFeatures::Scope use_sse2(SSE2); | 8907 CpuFeatures::Scope use_sse2(SSE2); |
8882 if (static_operands_type_.IsNumber()) { | 8908 if (static_operands_type_.IsNumber()) { |
8883 if (FLAG_debug_code) { | 8909 if (FLAG_debug_code) { |
8884 // Assert at runtime that inputs are only numbers. | 8910 // Assert at runtime that inputs are only numbers. |
8885 __ AbortIfNotNumber(edx, | 8911 __ AbortIfNotNumber(edx); |
8886 "GenericBinaryOpStub operand not a number."); | 8912 __ AbortIfNotNumber(eax); |
8887 __ AbortIfNotNumber(eax, | |
8888 "GenericBinaryOpStub operand not a number."); | |
8889 } | 8913 } |
8890 if (static_operands_type_.IsSmi()) { | 8914 if (static_operands_type_.IsSmi()) { |
| 8915 if (FLAG_debug_code) { |
| 8916 __ AbortIfNotSmi(edx); |
| 8917 __ AbortIfNotSmi(eax); |
| 8918 } |
8891 FloatingPointHelper::LoadSSE2Smis(masm, ecx); | 8919 FloatingPointHelper::LoadSSE2Smis(masm, ecx); |
8892 } else { | 8920 } else { |
8893 FloatingPointHelper::LoadSSE2Operands(masm); | 8921 FloatingPointHelper::LoadSSE2Operands(masm); |
8894 } | 8922 } |
8895 } else { | 8923 } else { |
8896 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); | 8924 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); |
8897 } | 8925 } |
8898 | 8926 |
8899 switch (op_) { | 8927 switch (op_) { |
8900 case Token::ADD: __ addsd(xmm0, xmm1); break; | 8928 case Token::ADD: __ addsd(xmm0, xmm1); break; |
8901 case Token::SUB: __ subsd(xmm0, xmm1); break; | 8929 case Token::SUB: __ subsd(xmm0, xmm1); break; |
8902 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 8930 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
8903 case Token::DIV: __ divsd(xmm0, xmm1); break; | 8931 case Token::DIV: __ divsd(xmm0, xmm1); break; |
8904 default: UNREACHABLE(); | 8932 default: UNREACHABLE(); |
8905 } | 8933 } |
8906 GenerateHeapResultAllocation(masm, &call_runtime); | 8934 GenerateHeapResultAllocation(masm, &call_runtime); |
8907 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 8935 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
8908 GenerateReturn(masm); | 8936 GenerateReturn(masm); |
8909 } else { // SSE2 not available, use FPU. | 8937 } else { // SSE2 not available, use FPU. |
8910 if (static_operands_type_.IsNumber()) { | 8938 if (static_operands_type_.IsNumber()) { |
8911 if (FLAG_debug_code) { | 8939 if (FLAG_debug_code) { |
8912 // Assert at runtime that inputs are only numbers. | 8940 // Assert at runtime that inputs are only numbers. |
8913 __ AbortIfNotNumber(edx, | 8941 __ AbortIfNotNumber(edx); |
8914 "GenericBinaryOpStub operand not a number."); | 8942 __ AbortIfNotNumber(eax); |
8915 __ AbortIfNotNumber(eax, | |
8916 "GenericBinaryOpStub operand not a number."); | |
8917 } | 8943 } |
8918 } else { | 8944 } else { |
8919 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); | 8945 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); |
8920 } | 8946 } |
8921 FloatingPointHelper::LoadFloatOperands( | 8947 FloatingPointHelper::LoadFloatOperands( |
8922 masm, | 8948 masm, |
8923 ecx, | 8949 ecx, |
8924 FloatingPointHelper::ARGS_IN_REGISTERS); | 8950 FloatingPointHelper::ARGS_IN_REGISTERS); |
8925 switch (op_) { | 8951 switch (op_) { |
8926 case Token::ADD: __ faddp(1); break; | 8952 case Token::ADD: __ faddp(1); break; |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9636 Label* conversion_failure) { | 9662 Label* conversion_failure) { |
9637 // Check float operands. | 9663 // Check float operands. |
9638 Label arg1_is_object, check_undefined_arg1; | 9664 Label arg1_is_object, check_undefined_arg1; |
9639 Label arg2_is_object, check_undefined_arg2; | 9665 Label arg2_is_object, check_undefined_arg2; |
9640 Label load_arg2, done; | 9666 Label load_arg2, done; |
9641 | 9667 |
9642 if (!number_info.IsHeapNumber()) { | 9668 if (!number_info.IsHeapNumber()) { |
9643 if (!number_info.IsSmi()) { | 9669 if (!number_info.IsSmi()) { |
9644 __ test(edx, Immediate(kSmiTagMask)); | 9670 __ test(edx, Immediate(kSmiTagMask)); |
9645 __ j(not_zero, &arg1_is_object); | 9671 __ j(not_zero, &arg1_is_object); |
| 9672 } else { |
| 9673 if (FLAG_debug_code) __ AbortIfNotSmi(edx); |
9646 } | 9674 } |
9647 __ SmiUntag(edx); | 9675 __ SmiUntag(edx); |
9648 __ jmp(&load_arg2); | 9676 __ jmp(&load_arg2); |
9649 } | 9677 } |
9650 | 9678 |
9651 __ bind(&arg1_is_object); | 9679 __ bind(&arg1_is_object); |
9652 | 9680 |
9653 // Get the untagged integer version of the edx heap number in ecx. | 9681 // Get the untagged integer version of the edx heap number in ecx. |
9654 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); | 9682 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); |
9655 __ mov(edx, ecx); | 9683 __ mov(edx, ecx); |
9656 | 9684 |
9657 // Here edx has the untagged integer, eax has a Smi or a heap number. | 9685 // Here edx has the untagged integer, eax has a Smi or a heap number. |
9658 __ bind(&load_arg2); | 9686 __ bind(&load_arg2); |
9659 if (!number_info.IsHeapNumber()) { | 9687 if (!number_info.IsHeapNumber()) { |
9660 // Test if arg2 is a Smi. | 9688 // Test if arg2 is a Smi. |
9661 if (!number_info.IsSmi()) { | 9689 if (!number_info.IsSmi()) { |
9662 __ test(eax, Immediate(kSmiTagMask)); | 9690 __ test(eax, Immediate(kSmiTagMask)); |
9663 __ j(not_zero, &arg2_is_object); | 9691 __ j(not_zero, &arg2_is_object); |
| 9692 } else { |
| 9693 if (FLAG_debug_code) __ AbortIfNotSmi(eax); |
9664 } | 9694 } |
9665 __ SmiUntag(eax); | 9695 __ SmiUntag(eax); |
9666 __ mov(ecx, eax); | 9696 __ mov(ecx, eax); |
9667 __ jmp(&done); | 9697 __ jmp(&done); |
9668 } | 9698 } |
9669 | 9699 |
9670 __ bind(&arg2_is_object); | 9700 __ bind(&arg2_is_object); |
9671 | 9701 |
9672 // Get the untagged integer version of the eax heap number in ecx. | 9702 // Get the untagged integer version of the eax heap number in ecx. |
9673 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); | 9703 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); |
(...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12242 | 12272 |
12243 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12273 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
12244 // tagged as a small integer. | 12274 // tagged as a small integer. |
12245 __ bind(&runtime); | 12275 __ bind(&runtime); |
12246 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12276 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
12247 } | 12277 } |
12248 | 12278 |
12249 #undef __ | 12279 #undef __ |
12250 | 12280 |
12251 } } // namespace v8::internal | 12281 } } // namespace v8::internal |
OLD | NEW |