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

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

Issue 1079006: Add basic C++ implementation of CPU profiler. (Closed)
Patch Set: Comments addressed 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
« no previous file with comments | « src/handles.cc ('k') | 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 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/handles.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698