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 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3734 // the bottom check of the loop condition. | 3752 // the bottom check of the loop condition. |
3735 if (node->is_fast_smi_loop()) { | 3753 if (node->is_fast_smi_loop()) { |
3736 // Set number type of the loop variable to smi. | 3754 // Set number type of the loop variable to smi. |
3737 Slot* slot = node->loop_variable()->slot(); | 3755 Slot* slot = node->loop_variable()->slot(); |
3738 ASSERT(slot->type() == Slot::LOCAL); | 3756 ASSERT(slot->type() == Slot::LOCAL); |
3739 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3757 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
3740 if (FLAG_debug_code) { | 3758 if (FLAG_debug_code) { |
3741 frame_->PushLocalAt(slot->index()); | 3759 frame_->PushLocalAt(slot->index()); |
3742 Result var = frame_->Pop(); | 3760 Result var = frame_->Pop(); |
3743 var.ToRegister(); | 3761 var.ToRegister(); |
3744 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3762 __ AbortIfNotSmi(var.reg()); |
3745 } | 3763 } |
3746 } | 3764 } |
3747 | 3765 |
3748 Visit(node->body()); | 3766 Visit(node->body()); |
3749 | 3767 |
3750 // If there is an update expression, compile it if necessary. | 3768 // If there is an update expression, compile it if necessary. |
3751 if (node->next() != NULL) { | 3769 if (node->next() != NULL) { |
3752 if (node->continue_target()->is_linked()) { | 3770 if (node->continue_target()->is_linked()) { |
3753 node->continue_target()->Bind(); | 3771 node->continue_target()->Bind(); |
3754 } | 3772 } |
(...skipping 13 matching lines...) Expand all Loading... |
3768 // expression if we are in a fast smi loop condition. | 3786 // expression if we are in a fast smi loop condition. |
3769 if (node->is_fast_smi_loop() && has_valid_frame()) { | 3787 if (node->is_fast_smi_loop() && has_valid_frame()) { |
3770 // Set number type of the loop variable to smi. | 3788 // Set number type of the loop variable to smi. |
3771 Slot* slot = node->loop_variable()->slot(); | 3789 Slot* slot = node->loop_variable()->slot(); |
3772 ASSERT(slot->type() == Slot::LOCAL); | 3790 ASSERT(slot->type() == Slot::LOCAL); |
3773 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3791 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
3774 if (FLAG_debug_code) { | 3792 if (FLAG_debug_code) { |
3775 frame_->PushLocalAt(slot->index()); | 3793 frame_->PushLocalAt(slot->index()); |
3776 Result var = frame_->Pop(); | 3794 Result var = frame_->Pop(); |
3777 var.ToRegister(); | 3795 var.ToRegister(); |
3778 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3796 __ AbortIfNotSmi(var.reg()); |
3779 } | 3797 } |
3780 } | 3798 } |
3781 | 3799 |
3782 // Based on the condition analysis, compile the backward jump as | 3800 // Based on the condition analysis, compile the backward jump as |
3783 // necessary. | 3801 // necessary. |
3784 switch (info) { | 3802 switch (info) { |
3785 case ALWAYS_TRUE: | 3803 case ALWAYS_TRUE: |
3786 if (has_valid_frame()) { | 3804 if (has_valid_frame()) { |
3787 if (node->next() == NULL) { | 3805 if (node->next() == NULL) { |
3788 node->continue_target()->Jump(); | 3806 node->continue_target()->Jump(); |
(...skipping 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6685 break; | 6703 break; |
6686 } | 6704 } |
6687 case Token::BIT_NOT: { | 6705 case Token::BIT_NOT: { |
6688 // Smi check. | 6706 // Smi check. |
6689 JumpTarget smi_label; | 6707 JumpTarget smi_label; |
6690 JumpTarget continue_label; | 6708 JumpTarget continue_label; |
6691 Result operand = frame_->Pop(); | 6709 Result operand = frame_->Pop(); |
6692 NumberInfo operand_info = operand.number_info(); | 6710 NumberInfo operand_info = operand.number_info(); |
6693 operand.ToRegister(); | 6711 operand.ToRegister(); |
6694 if (operand_info.IsSmi()) { | 6712 if (operand_info.IsSmi()) { |
6695 if (FLAG_debug_code) { | 6713 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg()); |
6696 __ AbortIfNotSmi(operand.reg(), "Operand not a smi."); | |
6697 } | |
6698 frame_->Spill(operand.reg()); | 6714 frame_->Spill(operand.reg()); |
6699 // Set smi tag bit. It will be reset by the not operation. | 6715 // Set smi tag bit. It will be reset by the not operation. |
6700 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); | 6716 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); |
6701 __ not_(operand.reg()); | 6717 __ not_(operand.reg()); |
6702 Result answer = operand; | 6718 Result answer = operand; |
6703 answer.set_number_info(NumberInfo::Smi()); | 6719 answer.set_number_info(NumberInfo::Smi()); |
6704 frame_->Push(&answer); | 6720 frame_->Push(&answer); |
6705 } else { | 6721 } else { |
6706 __ test(operand.reg(), Immediate(kSmiTagMask)); | 6722 __ test(operand.reg(), Immediate(kSmiTagMask)); |
6707 smi_label.Branch(zero, &operand, taken); | 6723 smi_label.Branch(zero, &operand, taken); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6887 // The return value for postfix operations is the | 6903 // The return value for postfix operations is the |
6888 // same as the input, and has the same number info. | 6904 // same as the input, and has the same number info. |
6889 old_value.set_number_info(new_value.number_info()); | 6905 old_value.set_number_info(new_value.number_info()); |
6890 } | 6906 } |
6891 | 6907 |
6892 // Ensure the new value is writable. | 6908 // Ensure the new value is writable. |
6893 frame_->Spill(new_value.reg()); | 6909 frame_->Spill(new_value.reg()); |
6894 | 6910 |
6895 Result tmp; | 6911 Result tmp; |
6896 if (new_value.is_smi()) { | 6912 if (new_value.is_smi()) { |
6897 if (FLAG_debug_code) { | 6913 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); |
6898 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi"); | |
6899 } | |
6900 } else { | 6914 } else { |
6901 // We don't know statically if the input is a smi. | 6915 // We don't know statically if the input is a smi. |
6902 // In order to combine the overflow and the smi tag check, we need | 6916 // In order to combine the overflow and the smi tag check, we need |
6903 // to be able to allocate a byte register. We attempt to do so | 6917 // to be able to allocate a byte register. We attempt to do so |
6904 // without spilling. If we fail, we will generate separate overflow | 6918 // without spilling. If we fail, we will generate separate overflow |
6905 // and smi tag checks. | 6919 // and smi tag checks. |
6906 // We allocate and clear a temporary byte register before performing | 6920 // We allocate and clear a temporary byte register before performing |
6907 // the count operation since clearing the register using xor will clear | 6921 // the count operation since clearing the register using xor will clear |
6908 // the overflow flag. | 6922 // the overflow flag. |
6909 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); | 6923 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7853 // Use masm-> here instead of the double underscore macro since extra | 7867 // Use masm-> here instead of the double underscore macro since extra |
7854 // coverage code can interfere with the patching. | 7868 // coverage code can interfere with the patching. |
7855 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 7869 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
7856 Immediate(Factory::null_value())); | 7870 Immediate(Factory::null_value())); |
7857 deferred->Branch(not_equal); | 7871 deferred->Branch(not_equal); |
7858 | 7872 |
7859 // Check that the key is a smi. | 7873 // Check that the key is a smi. |
7860 if (!key.is_smi()) { | 7874 if (!key.is_smi()) { |
7861 __ test(key.reg(), Immediate(kSmiTagMask)); | 7875 __ test(key.reg(), Immediate(kSmiTagMask)); |
7862 deferred->Branch(not_zero); | 7876 deferred->Branch(not_zero); |
| 7877 } else { |
| 7878 if (FLAG_debug_code) __ AbortIfNotSmi(key.reg()); |
7863 } | 7879 } |
7864 | 7880 |
7865 // Get the elements array from the receiver and check that it | 7881 // Get the elements array from the receiver and check that it |
7866 // is not a dictionary. | 7882 // is not a dictionary. |
7867 __ mov(elements.reg(), | 7883 __ mov(elements.reg(), |
7868 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 7884 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
7869 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), | 7885 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
7870 Immediate(Factory::fixed_array_map())); | 7886 Immediate(Factory::fixed_array_map())); |
7871 deferred->Branch(not_equal); | 7887 deferred->Branch(not_equal); |
7872 | 7888 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8006 | 8022 |
8007 | 8023 |
8008 static void CheckTwoForSminess(MacroAssembler* masm, | 8024 static void CheckTwoForSminess(MacroAssembler* masm, |
8009 Register left, Register right, Register scratch, | 8025 Register left, Register right, Register scratch, |
8010 NumberInfo left_info, NumberInfo right_info, | 8026 NumberInfo left_info, NumberInfo right_info, |
8011 DeferredInlineBinaryOperation* deferred) { | 8027 DeferredInlineBinaryOperation* deferred) { |
8012 if (left.is(right)) { | 8028 if (left.is(right)) { |
8013 if (!left_info.IsSmi()) { | 8029 if (!left_info.IsSmi()) { |
8014 __ test(left, Immediate(kSmiTagMask)); | 8030 __ test(left, Immediate(kSmiTagMask)); |
8015 deferred->Branch(not_zero); | 8031 deferred->Branch(not_zero); |
| 8032 } else { |
| 8033 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
8016 } | 8034 } |
8017 } else if (!left_info.IsSmi()) { | 8035 } else if (!left_info.IsSmi()) { |
8018 if (!right_info.IsSmi()) { | 8036 if (!right_info.IsSmi()) { |
8019 __ mov(scratch, left); | 8037 __ mov(scratch, left); |
8020 __ or_(scratch, Operand(right)); | 8038 __ or_(scratch, Operand(right)); |
8021 __ test(scratch, Immediate(kSmiTagMask)); | 8039 __ test(scratch, Immediate(kSmiTagMask)); |
8022 deferred->Branch(not_zero); | 8040 deferred->Branch(not_zero); |
8023 } else { | 8041 } else { |
8024 __ test(left, Immediate(kSmiTagMask)); | 8042 __ test(left, Immediate(kSmiTagMask)); |
8025 deferred->Branch(not_zero); | 8043 deferred->Branch(not_zero); |
| 8044 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
8026 } | 8045 } |
8027 } else { | 8046 } else { |
| 8047 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
8028 if (!right_info.IsSmi()) { | 8048 if (!right_info.IsSmi()) { |
8029 __ test(right, Immediate(kSmiTagMask)); | 8049 __ test(right, Immediate(kSmiTagMask)); |
8030 deferred->Branch(not_zero); | 8050 deferred->Branch(not_zero); |
| 8051 } else { |
| 8052 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
8031 } | 8053 } |
8032 } | 8054 } |
8033 } | 8055 } |
8034 | 8056 |
8035 | 8057 |
8036 Handle<String> Reference::GetName() { | 8058 Handle<String> Reference::GetName() { |
8037 ASSERT(type_ == NAMED); | 8059 ASSERT(type_ == NAMED); |
8038 Property* property = expression_->AsProperty(); | 8060 Property* property = expression_->AsProperty(); |
8039 if (property == NULL) { | 8061 if (property == NULL) { |
8040 // Global variable reference treated as a named property reference. | 8062 // Global variable reference treated as a named property reference. |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8527 __ mov(ebx, eax); | 8549 __ mov(ebx, eax); |
8528 __ mov(eax, edx); | 8550 __ mov(eax, edx); |
8529 } | 8551 } |
8530 } | 8552 } |
8531 if (!HasArgsInRegisters()) { | 8553 if (!HasArgsInRegisters()) { |
8532 __ mov(right, Operand(esp, 1 * kPointerSize)); | 8554 __ mov(right, Operand(esp, 1 * kPointerSize)); |
8533 __ mov(left, Operand(esp, 2 * kPointerSize)); | 8555 __ mov(left, Operand(esp, 2 * kPointerSize)); |
8534 } | 8556 } |
8535 | 8557 |
8536 if (static_operands_type_.IsSmi()) { | 8558 if (static_operands_type_.IsSmi()) { |
| 8559 if (FLAG_debug_code) { |
| 8560 __ AbortIfNotSmi(left); |
| 8561 __ AbortIfNotSmi(right); |
| 8562 } |
8537 if (op_ == Token::BIT_OR) { | 8563 if (op_ == Token::BIT_OR) { |
8538 __ or_(right, Operand(left)); | 8564 __ or_(right, Operand(left)); |
8539 GenerateReturn(masm); | 8565 GenerateReturn(masm); |
8540 return; | 8566 return; |
8541 } else if (op_ == Token::BIT_AND) { | 8567 } else if (op_ == Token::BIT_AND) { |
8542 __ and_(right, Operand(left)); | 8568 __ and_(right, Operand(left)); |
8543 GenerateReturn(masm); | 8569 GenerateReturn(masm); |
8544 return; | 8570 return; |
8545 } else if (op_ == Token::BIT_XOR) { | 8571 } else if (op_ == Token::BIT_XOR) { |
8546 __ xor_(right, Operand(left)); | 8572 __ xor_(right, Operand(left)); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8881 // forever for all other operations (also if smi code is skipped). | 8907 // forever for all other operations (also if smi code is skipped). |
8882 GenerateTypeTransition(masm); | 8908 GenerateTypeTransition(masm); |
8883 } | 8909 } |
8884 | 8910 |
8885 Label not_floats; | 8911 Label not_floats; |
8886 if (CpuFeatures::IsSupported(SSE2)) { | 8912 if (CpuFeatures::IsSupported(SSE2)) { |
8887 CpuFeatures::Scope use_sse2(SSE2); | 8913 CpuFeatures::Scope use_sse2(SSE2); |
8888 if (static_operands_type_.IsNumber()) { | 8914 if (static_operands_type_.IsNumber()) { |
8889 if (FLAG_debug_code) { | 8915 if (FLAG_debug_code) { |
8890 // Assert at runtime that inputs are only numbers. | 8916 // Assert at runtime that inputs are only numbers. |
8891 __ AbortIfNotNumber(edx, | 8917 __ AbortIfNotNumber(edx); |
8892 "GenericBinaryOpStub operand not a number."); | 8918 __ AbortIfNotNumber(eax); |
8893 __ AbortIfNotNumber(eax, | |
8894 "GenericBinaryOpStub operand not a number."); | |
8895 } | 8919 } |
8896 if (static_operands_type_.IsSmi()) { | 8920 if (static_operands_type_.IsSmi()) { |
| 8921 if (FLAG_debug_code) { |
| 8922 __ AbortIfNotSmi(edx); |
| 8923 __ AbortIfNotSmi(eax); |
| 8924 } |
8897 FloatingPointHelper::LoadSSE2Smis(masm, ecx); | 8925 FloatingPointHelper::LoadSSE2Smis(masm, ecx); |
8898 } else { | 8926 } else { |
8899 FloatingPointHelper::LoadSSE2Operands(masm); | 8927 FloatingPointHelper::LoadSSE2Operands(masm); |
8900 } | 8928 } |
8901 } else { | 8929 } else { |
8902 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); | 8930 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); |
8903 } | 8931 } |
8904 | 8932 |
8905 switch (op_) { | 8933 switch (op_) { |
8906 case Token::ADD: __ addsd(xmm0, xmm1); break; | 8934 case Token::ADD: __ addsd(xmm0, xmm1); break; |
8907 case Token::SUB: __ subsd(xmm0, xmm1); break; | 8935 case Token::SUB: __ subsd(xmm0, xmm1); break; |
8908 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 8936 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
8909 case Token::DIV: __ divsd(xmm0, xmm1); break; | 8937 case Token::DIV: __ divsd(xmm0, xmm1); break; |
8910 default: UNREACHABLE(); | 8938 default: UNREACHABLE(); |
8911 } | 8939 } |
8912 GenerateHeapResultAllocation(masm, &call_runtime); | 8940 GenerateHeapResultAllocation(masm, &call_runtime); |
8913 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 8941 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
8914 GenerateReturn(masm); | 8942 GenerateReturn(masm); |
8915 } else { // SSE2 not available, use FPU. | 8943 } else { // SSE2 not available, use FPU. |
8916 if (static_operands_type_.IsNumber()) { | 8944 if (static_operands_type_.IsNumber()) { |
8917 if (FLAG_debug_code) { | 8945 if (FLAG_debug_code) { |
8918 // Assert at runtime that inputs are only numbers. | 8946 // Assert at runtime that inputs are only numbers. |
8919 __ AbortIfNotNumber(edx, | 8947 __ AbortIfNotNumber(edx); |
8920 "GenericBinaryOpStub operand not a number."); | 8948 __ AbortIfNotNumber(eax); |
8921 __ AbortIfNotNumber(eax, | |
8922 "GenericBinaryOpStub operand not a number."); | |
8923 } | 8949 } |
8924 } else { | 8950 } else { |
8925 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); | 8951 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); |
8926 } | 8952 } |
8927 FloatingPointHelper::LoadFloatOperands( | 8953 FloatingPointHelper::LoadFloatOperands( |
8928 masm, | 8954 masm, |
8929 ecx, | 8955 ecx, |
8930 FloatingPointHelper::ARGS_IN_REGISTERS); | 8956 FloatingPointHelper::ARGS_IN_REGISTERS); |
8931 switch (op_) { | 8957 switch (op_) { |
8932 case Token::ADD: __ faddp(1); break; | 8958 case Token::ADD: __ faddp(1); break; |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9642 Label* conversion_failure) { | 9668 Label* conversion_failure) { |
9643 // Check float operands. | 9669 // Check float operands. |
9644 Label arg1_is_object, check_undefined_arg1; | 9670 Label arg1_is_object, check_undefined_arg1; |
9645 Label arg2_is_object, check_undefined_arg2; | 9671 Label arg2_is_object, check_undefined_arg2; |
9646 Label load_arg2, done; | 9672 Label load_arg2, done; |
9647 | 9673 |
9648 if (!number_info.IsHeapNumber()) { | 9674 if (!number_info.IsHeapNumber()) { |
9649 if (!number_info.IsSmi()) { | 9675 if (!number_info.IsSmi()) { |
9650 __ test(edx, Immediate(kSmiTagMask)); | 9676 __ test(edx, Immediate(kSmiTagMask)); |
9651 __ j(not_zero, &arg1_is_object); | 9677 __ j(not_zero, &arg1_is_object); |
| 9678 } else { |
| 9679 if (FLAG_debug_code) __ AbortIfNotSmi(edx); |
9652 } | 9680 } |
9653 __ SmiUntag(edx); | 9681 __ SmiUntag(edx); |
9654 __ jmp(&load_arg2); | 9682 __ jmp(&load_arg2); |
9655 } | 9683 } |
9656 | 9684 |
9657 __ bind(&arg1_is_object); | 9685 __ bind(&arg1_is_object); |
9658 | 9686 |
9659 // Get the untagged integer version of the edx heap number in ecx. | 9687 // Get the untagged integer version of the edx heap number in ecx. |
9660 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); | 9688 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); |
9661 __ mov(edx, ecx); | 9689 __ mov(edx, ecx); |
9662 | 9690 |
9663 // Here edx has the untagged integer, eax has a Smi or a heap number. | 9691 // Here edx has the untagged integer, eax has a Smi or a heap number. |
9664 __ bind(&load_arg2); | 9692 __ bind(&load_arg2); |
9665 if (!number_info.IsHeapNumber()) { | 9693 if (!number_info.IsHeapNumber()) { |
9666 // Test if arg2 is a Smi. | 9694 // Test if arg2 is a Smi. |
9667 if (!number_info.IsSmi()) { | 9695 if (!number_info.IsSmi()) { |
9668 __ test(eax, Immediate(kSmiTagMask)); | 9696 __ test(eax, Immediate(kSmiTagMask)); |
9669 __ j(not_zero, &arg2_is_object); | 9697 __ j(not_zero, &arg2_is_object); |
| 9698 } else { |
| 9699 if (FLAG_debug_code) __ AbortIfNotSmi(eax); |
9670 } | 9700 } |
9671 __ SmiUntag(eax); | 9701 __ SmiUntag(eax); |
9672 __ mov(ecx, eax); | 9702 __ mov(ecx, eax); |
9673 __ jmp(&done); | 9703 __ jmp(&done); |
9674 } | 9704 } |
9675 | 9705 |
9676 __ bind(&arg2_is_object); | 9706 __ bind(&arg2_is_object); |
9677 | 9707 |
9678 // Get the untagged integer version of the eax heap number in ecx. | 9708 // Get the untagged integer version of the eax heap number in ecx. |
9679 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); | 9709 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); |
(...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12248 | 12278 |
12249 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12279 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
12250 // tagged as a small integer. | 12280 // tagged as a small integer. |
12251 __ bind(&runtime); | 12281 __ bind(&runtime); |
12252 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12282 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
12253 } | 12283 } |
12254 | 12284 |
12255 #undef __ | 12285 #undef __ |
12256 | 12286 |
12257 } } // namespace v8::internal | 12287 } } // namespace v8::internal |
OLD | NEW |