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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 998007: Add debug code assertions where we expect smi inputs. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698