| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 VisitForAccumulatorValue(stmt->enumerable()); | 810 VisitForAccumulatorValue(stmt->enumerable()); |
| 811 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 811 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 812 __ cmp(r0, ip); | 812 __ cmp(r0, ip); |
| 813 __ b(eq, &exit); | 813 __ b(eq, &exit); |
| 814 __ LoadRoot(ip, Heap::kNullValueRootIndex); | 814 __ LoadRoot(ip, Heap::kNullValueRootIndex); |
| 815 __ cmp(r0, ip); | 815 __ cmp(r0, ip); |
| 816 __ b(eq, &exit); | 816 __ b(eq, &exit); |
| 817 | 817 |
| 818 // Convert the object to a JS object. | 818 // Convert the object to a JS object. |
| 819 Label convert, done_convert; | 819 Label convert, done_convert; |
| 820 __ BranchOnSmi(r0, &convert); | 820 __ JumpIfSmi(r0, &convert); |
| 821 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); | 821 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); |
| 822 __ b(hs, &done_convert); | 822 __ b(hs, &done_convert); |
| 823 __ bind(&convert); | 823 __ bind(&convert); |
| 824 __ push(r0); | 824 __ push(r0); |
| 825 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); | 825 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); |
| 826 __ bind(&done_convert); | 826 __ bind(&done_convert); |
| 827 __ push(r0); | 827 __ push(r0); |
| 828 | 828 |
| 829 // BUG(867): Check cache validity in generated code. This is a fast | 829 // BUG(867): Check cache validity in generated code. This is a fast |
| 830 // case for the JSObject::IsSimpleEnum cache validity checks. If we | 830 // case for the JSObject::IsSimpleEnum cache validity checks. If we |
| (...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2128 | 2128 |
| 2129 VisitForAccumulatorValue(args->at(0)); | 2129 VisitForAccumulatorValue(args->at(0)); |
| 2130 | 2130 |
| 2131 Label materialize_true, materialize_false; | 2131 Label materialize_true, materialize_false; |
| 2132 Label* if_true = NULL; | 2132 Label* if_true = NULL; |
| 2133 Label* if_false = NULL; | 2133 Label* if_false = NULL; |
| 2134 Label* fall_through = NULL; | 2134 Label* fall_through = NULL; |
| 2135 context()->PrepareTest(&materialize_true, &materialize_false, | 2135 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2136 &if_true, &if_false, &fall_through); | 2136 &if_true, &if_false, &fall_through); |
| 2137 | 2137 |
| 2138 __ BranchOnSmi(r0, if_false); | 2138 __ JumpIfSmi(r0, if_false); |
| 2139 __ LoadRoot(ip, Heap::kNullValueRootIndex); | 2139 __ LoadRoot(ip, Heap::kNullValueRootIndex); |
| 2140 __ cmp(r0, ip); | 2140 __ cmp(r0, ip); |
| 2141 __ b(eq, if_true); | 2141 __ b(eq, if_true); |
| 2142 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); | 2142 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 2143 // Undetectable objects behave like undefined when tested with typeof. | 2143 // Undetectable objects behave like undefined when tested with typeof. |
| 2144 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); | 2144 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); |
| 2145 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 2145 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
| 2146 __ b(ne, if_false); | 2146 __ b(ne, if_false); |
| 2147 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 2147 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
| 2148 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); | 2148 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2160 | 2160 |
| 2161 VisitForAccumulatorValue(args->at(0)); | 2161 VisitForAccumulatorValue(args->at(0)); |
| 2162 | 2162 |
| 2163 Label materialize_true, materialize_false; | 2163 Label materialize_true, materialize_false; |
| 2164 Label* if_true = NULL; | 2164 Label* if_true = NULL; |
| 2165 Label* if_false = NULL; | 2165 Label* if_false = NULL; |
| 2166 Label* fall_through = NULL; | 2166 Label* fall_through = NULL; |
| 2167 context()->PrepareTest(&materialize_true, &materialize_false, | 2167 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2168 &if_true, &if_false, &fall_through); | 2168 &if_true, &if_false, &fall_through); |
| 2169 | 2169 |
| 2170 __ BranchOnSmi(r0, if_false); | 2170 __ JumpIfSmi(r0, if_false); |
| 2171 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); | 2171 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); |
| 2172 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2172 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 2173 Split(ge, if_true, if_false, fall_through); | 2173 Split(ge, if_true, if_false, fall_through); |
| 2174 | 2174 |
| 2175 context()->Plug(if_true, if_false); | 2175 context()->Plug(if_true, if_false); |
| 2176 } | 2176 } |
| 2177 | 2177 |
| 2178 | 2178 |
| 2179 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { | 2179 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { |
| 2180 ASSERT(args->length() == 1); | 2180 ASSERT(args->length() == 1); |
| 2181 | 2181 |
| 2182 VisitForAccumulatorValue(args->at(0)); | 2182 VisitForAccumulatorValue(args->at(0)); |
| 2183 | 2183 |
| 2184 Label materialize_true, materialize_false; | 2184 Label materialize_true, materialize_false; |
| 2185 Label* if_true = NULL; | 2185 Label* if_true = NULL; |
| 2186 Label* if_false = NULL; | 2186 Label* if_false = NULL; |
| 2187 Label* fall_through = NULL; | 2187 Label* fall_through = NULL; |
| 2188 context()->PrepareTest(&materialize_true, &materialize_false, | 2188 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2189 &if_true, &if_false, &fall_through); | 2189 &if_true, &if_false, &fall_through); |
| 2190 | 2190 |
| 2191 __ BranchOnSmi(r0, if_false); | 2191 __ JumpIfSmi(r0, if_false); |
| 2192 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); | 2192 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 2193 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); | 2193 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); |
| 2194 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 2194 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
| 2195 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2195 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 2196 Split(ne, if_true, if_false, fall_through); | 2196 Split(ne, if_true, if_false, fall_through); |
| 2197 | 2197 |
| 2198 context()->Plug(if_true, if_false); | 2198 context()->Plug(if_true, if_false); |
| 2199 } | 2199 } |
| 2200 | 2200 |
| 2201 | 2201 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2227 | 2227 |
| 2228 VisitForAccumulatorValue(args->at(0)); | 2228 VisitForAccumulatorValue(args->at(0)); |
| 2229 | 2229 |
| 2230 Label materialize_true, materialize_false; | 2230 Label materialize_true, materialize_false; |
| 2231 Label* if_true = NULL; | 2231 Label* if_true = NULL; |
| 2232 Label* if_false = NULL; | 2232 Label* if_false = NULL; |
| 2233 Label* fall_through = NULL; | 2233 Label* fall_through = NULL; |
| 2234 context()->PrepareTest(&materialize_true, &materialize_false, | 2234 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2235 &if_true, &if_false, &fall_through); | 2235 &if_true, &if_false, &fall_through); |
| 2236 | 2236 |
| 2237 __ BranchOnSmi(r0, if_false); | 2237 __ JumpIfSmi(r0, if_false); |
| 2238 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); | 2238 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); |
| 2239 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2239 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 2240 Split(eq, if_true, if_false, fall_through); | 2240 Split(eq, if_true, if_false, fall_through); |
| 2241 | 2241 |
| 2242 context()->Plug(if_true, if_false); | 2242 context()->Plug(if_true, if_false); |
| 2243 } | 2243 } |
| 2244 | 2244 |
| 2245 | 2245 |
| 2246 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { | 2246 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { |
| 2247 ASSERT(args->length() == 1); | 2247 ASSERT(args->length() == 1); |
| 2248 | 2248 |
| 2249 VisitForAccumulatorValue(args->at(0)); | 2249 VisitForAccumulatorValue(args->at(0)); |
| 2250 | 2250 |
| 2251 Label materialize_true, materialize_false; | 2251 Label materialize_true, materialize_false; |
| 2252 Label* if_true = NULL; | 2252 Label* if_true = NULL; |
| 2253 Label* if_false = NULL; | 2253 Label* if_false = NULL; |
| 2254 Label* fall_through = NULL; | 2254 Label* fall_through = NULL; |
| 2255 context()->PrepareTest(&materialize_true, &materialize_false, | 2255 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2256 &if_true, &if_false, &fall_through); | 2256 &if_true, &if_false, &fall_through); |
| 2257 | 2257 |
| 2258 __ BranchOnSmi(r0, if_false); | 2258 __ JumpIfSmi(r0, if_false); |
| 2259 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); | 2259 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); |
| 2260 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2260 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 2261 Split(eq, if_true, if_false, fall_through); | 2261 Split(eq, if_true, if_false, fall_through); |
| 2262 | 2262 |
| 2263 context()->Plug(if_true, if_false); | 2263 context()->Plug(if_true, if_false); |
| 2264 } | 2264 } |
| 2265 | 2265 |
| 2266 | 2266 |
| 2267 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { | 2267 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { |
| 2268 ASSERT(args->length() == 1); | 2268 ASSERT(args->length() == 1); |
| 2269 | 2269 |
| 2270 VisitForAccumulatorValue(args->at(0)); | 2270 VisitForAccumulatorValue(args->at(0)); |
| 2271 | 2271 |
| 2272 Label materialize_true, materialize_false; | 2272 Label materialize_true, materialize_false; |
| 2273 Label* if_true = NULL; | 2273 Label* if_true = NULL; |
| 2274 Label* if_false = NULL; | 2274 Label* if_false = NULL; |
| 2275 Label* fall_through = NULL; | 2275 Label* fall_through = NULL; |
| 2276 context()->PrepareTest(&materialize_true, &materialize_false, | 2276 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2277 &if_true, &if_false, &fall_through); | 2277 &if_true, &if_false, &fall_through); |
| 2278 | 2278 |
| 2279 __ BranchOnSmi(r0, if_false); | 2279 __ JumpIfSmi(r0, if_false); |
| 2280 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); | 2280 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); |
| 2281 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2281 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 2282 Split(eq, if_true, if_false, fall_through); | 2282 Split(eq, if_true, if_false, fall_through); |
| 2283 | 2283 |
| 2284 context()->Plug(if_true, if_false); | 2284 context()->Plug(if_true, if_false); |
| 2285 } | 2285 } |
| 2286 | 2286 |
| 2287 | 2287 |
| 2288 | 2288 |
| 2289 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { | 2289 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2376 } | 2376 } |
| 2377 | 2377 |
| 2378 | 2378 |
| 2379 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { | 2379 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { |
| 2380 ASSERT(args->length() == 1); | 2380 ASSERT(args->length() == 1); |
| 2381 Label done, null, function, non_function_constructor; | 2381 Label done, null, function, non_function_constructor; |
| 2382 | 2382 |
| 2383 VisitForAccumulatorValue(args->at(0)); | 2383 VisitForAccumulatorValue(args->at(0)); |
| 2384 | 2384 |
| 2385 // If the object is a smi, we return null. | 2385 // If the object is a smi, we return null. |
| 2386 __ BranchOnSmi(r0, &null); | 2386 __ JumpIfSmi(r0, &null); |
| 2387 | 2387 |
| 2388 // Check that the object is a JS object but take special care of JS | 2388 // Check that the object is a JS object but take special care of JS |
| 2389 // functions to make sure they have 'Function' as their class. | 2389 // functions to make sure they have 'Function' as their class. |
| 2390 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); // Map is now in r0. | 2390 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); // Map is now in r0. |
| 2391 __ b(lt, &null); | 2391 __ b(lt, &null); |
| 2392 | 2392 |
| 2393 // As long as JS_FUNCTION_TYPE is the last instance type and it is | 2393 // As long as JS_FUNCTION_TYPE is the last instance type and it is |
| 2394 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for | 2394 // right after LAST_JS_OBJECT_TYPE, we can avoid checking for |
| 2395 // LAST_JS_OBJECT_TYPE. | 2395 // LAST_JS_OBJECT_TYPE. |
| 2396 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 2396 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2527 } | 2527 } |
| 2528 | 2528 |
| 2529 | 2529 |
| 2530 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { | 2530 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { |
| 2531 ASSERT(args->length() == 1); | 2531 ASSERT(args->length() == 1); |
| 2532 | 2532 |
| 2533 VisitForAccumulatorValue(args->at(0)); // Load the object. | 2533 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 2534 | 2534 |
| 2535 Label done; | 2535 Label done; |
| 2536 // If the object is a smi return the object. | 2536 // If the object is a smi return the object. |
| 2537 __ BranchOnSmi(r0, &done); | 2537 __ JumpIfSmi(r0, &done); |
| 2538 // If the object is not a value type, return the object. | 2538 // If the object is not a value type, return the object. |
| 2539 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); | 2539 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); |
| 2540 __ b(ne, &done); | 2540 __ b(ne, &done); |
| 2541 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); | 2541 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); |
| 2542 | 2542 |
| 2543 __ bind(&done); | 2543 __ bind(&done); |
| 2544 context()->Plug(r0); | 2544 context()->Plug(r0); |
| 2545 } | 2545 } |
| 2546 | 2546 |
| 2547 | 2547 |
| 2548 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { | 2548 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { |
| 2549 // Load the arguments on the stack and call the runtime function. | 2549 // Load the arguments on the stack and call the runtime function. |
| 2550 ASSERT(args->length() == 2); | 2550 ASSERT(args->length() == 2); |
| 2551 VisitForStackValue(args->at(0)); | 2551 VisitForStackValue(args->at(0)); |
| 2552 VisitForStackValue(args->at(1)); | 2552 VisitForStackValue(args->at(1)); |
| 2553 __ CallRuntime(Runtime::kMath_pow, 2); | 2553 __ CallRuntime(Runtime::kMath_pow, 2); |
| 2554 context()->Plug(r0); | 2554 context()->Plug(r0); |
| 2555 } | 2555 } |
| 2556 | 2556 |
| 2557 | 2557 |
| 2558 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { | 2558 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { |
| 2559 ASSERT(args->length() == 2); | 2559 ASSERT(args->length() == 2); |
| 2560 | 2560 |
| 2561 VisitForStackValue(args->at(0)); // Load the object. | 2561 VisitForStackValue(args->at(0)); // Load the object. |
| 2562 VisitForAccumulatorValue(args->at(1)); // Load the value. | 2562 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 2563 __ pop(r1); // r0 = value. r1 = object. | 2563 __ pop(r1); // r0 = value. r1 = object. |
| 2564 | 2564 |
| 2565 Label done; | 2565 Label done; |
| 2566 // If the object is a smi, return the value. | 2566 // If the object is a smi, return the value. |
| 2567 __ BranchOnSmi(r1, &done); | 2567 __ JumpIfSmi(r1, &done); |
| 2568 | 2568 |
| 2569 // If the object is not a value type, return the value. | 2569 // If the object is not a value type, return the value. |
| 2570 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); | 2570 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); |
| 2571 __ b(ne, &done); | 2571 __ b(ne, &done); |
| 2572 | 2572 |
| 2573 // Store the value. | 2573 // Store the value. |
| 2574 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); | 2574 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); |
| 2575 // Update the write barrier. Save the value as it will be | 2575 // Update the write barrier. Save the value as it will be |
| 2576 // overwritten by the write barrier code and is needed afterward. | 2576 // overwritten by the write barrier code and is needed afterward. |
| 2577 __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3); | 2577 __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3); |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3080 | 3080 |
| 3081 case Token::BIT_NOT: { | 3081 case Token::BIT_NOT: { |
| 3082 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); | 3082 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); |
| 3083 // The generic unary operation stub expects the argument to be | 3083 // The generic unary operation stub expects the argument to be |
| 3084 // in the accumulator register r0. | 3084 // in the accumulator register r0. |
| 3085 VisitForAccumulatorValue(expr->expression()); | 3085 VisitForAccumulatorValue(expr->expression()); |
| 3086 Label done; | 3086 Label done; |
| 3087 bool inline_smi_code = ShouldInlineSmiCase(expr->op()); | 3087 bool inline_smi_code = ShouldInlineSmiCase(expr->op()); |
| 3088 if (inline_smi_code) { | 3088 if (inline_smi_code) { |
| 3089 Label call_stub; | 3089 Label call_stub; |
| 3090 __ BranchOnNotSmi(r0, &call_stub); | 3090 __ JumpIfNotSmi(r0, &call_stub); |
| 3091 __ mvn(r0, Operand(r0)); | 3091 __ mvn(r0, Operand(r0)); |
| 3092 // Bit-clear inverted smi-tag. | 3092 // Bit-clear inverted smi-tag. |
| 3093 __ bic(r0, r0, Operand(kSmiTagMask)); | 3093 __ bic(r0, r0, Operand(kSmiTagMask)); |
| 3094 __ b(&done); | 3094 __ b(&done); |
| 3095 __ bind(&call_stub); | 3095 __ bind(&call_stub); |
| 3096 } | 3096 } |
| 3097 bool overwrite = expr->expression()->ResultOverwriteAllowed(); | 3097 bool overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 3098 UnaryOpFlags flags = inline_smi_code | 3098 UnaryOpFlags flags = inline_smi_code |
| 3099 ? NO_UNARY_SMI_CODE_IN_STUB | 3099 ? NO_UNARY_SMI_CODE_IN_STUB |
| 3100 : NO_UNARY_FLAGS; | 3100 : NO_UNARY_FLAGS; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3167 EmitKeyedPropertyLoad(prop); | 3167 EmitKeyedPropertyLoad(prop); |
| 3168 } | 3168 } |
| 3169 } | 3169 } |
| 3170 | 3170 |
| 3171 // We need a second deoptimization point after loading the value | 3171 // We need a second deoptimization point after loading the value |
| 3172 // in case evaluating the property load my have a side effect. | 3172 // in case evaluating the property load my have a side effect. |
| 3173 PrepareForBailout(expr->increment(), TOS_REG); | 3173 PrepareForBailout(expr->increment(), TOS_REG); |
| 3174 | 3174 |
| 3175 // Call ToNumber only if operand is not a smi. | 3175 // Call ToNumber only if operand is not a smi. |
| 3176 Label no_conversion; | 3176 Label no_conversion; |
| 3177 __ BranchOnSmi(r0, &no_conversion); | 3177 __ JumpIfSmi(r0, &no_conversion); |
| 3178 __ push(r0); | 3178 __ push(r0); |
| 3179 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); | 3179 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); |
| 3180 __ bind(&no_conversion); | 3180 __ bind(&no_conversion); |
| 3181 | 3181 |
| 3182 // Save result for postfix expressions. | 3182 // Save result for postfix expressions. |
| 3183 if (expr->is_postfix()) { | 3183 if (expr->is_postfix()) { |
| 3184 if (!context()->IsEffect()) { | 3184 if (!context()->IsEffect()) { |
| 3185 // Save the result on the stack. If we have a named or keyed property | 3185 // Save the result on the stack. If we have a named or keyed property |
| 3186 // we store the result under the receiver that is currently on top | 3186 // we store the result under the receiver that is currently on top |
| 3187 // of the stack. | 3187 // of the stack. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3201 | 3201 |
| 3202 | 3202 |
| 3203 // Inline smi case if we are in a loop. | 3203 // Inline smi case if we are in a loop. |
| 3204 Label stub_call, done; | 3204 Label stub_call, done; |
| 3205 int count_value = expr->op() == Token::INC ? 1 : -1; | 3205 int count_value = expr->op() == Token::INC ? 1 : -1; |
| 3206 if (ShouldInlineSmiCase(expr->op())) { | 3206 if (ShouldInlineSmiCase(expr->op())) { |
| 3207 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); | 3207 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); |
| 3208 __ b(vs, &stub_call); | 3208 __ b(vs, &stub_call); |
| 3209 // We could eliminate this smi check if we split the code at | 3209 // We could eliminate this smi check if we split the code at |
| 3210 // the first smi check before calling ToNumber. | 3210 // the first smi check before calling ToNumber. |
| 3211 __ BranchOnSmi(r0, &done); | 3211 __ JumpIfSmi(r0, &done); |
| 3212 __ bind(&stub_call); | 3212 __ bind(&stub_call); |
| 3213 // Call stub. Undo operation first. | 3213 // Call stub. Undo operation first. |
| 3214 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); | 3214 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); |
| 3215 } | 3215 } |
| 3216 __ mov(r1, Operand(Smi::FromInt(count_value))); | 3216 __ mov(r1, Operand(Smi::FromInt(count_value))); |
| 3217 | 3217 |
| 3218 // Record position before stub call. | 3218 // Record position before stub call. |
| 3219 SetSourcePosition(expr->position()); | 3219 SetSourcePosition(expr->position()); |
| 3220 | 3220 |
| 3221 GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE, r1, r0); | 3221 GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE, r1, r0); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3494 case Token::IN: | 3494 case Token::IN: |
| 3495 case Token::INSTANCEOF: | 3495 case Token::INSTANCEOF: |
| 3496 default: | 3496 default: |
| 3497 UNREACHABLE(); | 3497 UNREACHABLE(); |
| 3498 } | 3498 } |
| 3499 | 3499 |
| 3500 bool inline_smi_code = ShouldInlineSmiCase(op); | 3500 bool inline_smi_code = ShouldInlineSmiCase(op); |
| 3501 if (inline_smi_code) { | 3501 if (inline_smi_code) { |
| 3502 Label slow_case; | 3502 Label slow_case; |
| 3503 __ orr(r2, r0, Operand(r1)); | 3503 __ orr(r2, r0, Operand(r1)); |
| 3504 __ BranchOnNotSmi(r2, &slow_case); | 3504 __ JumpIfNotSmi(r2, &slow_case); |
| 3505 __ cmp(r1, r0); | 3505 __ cmp(r1, r0); |
| 3506 Split(cc, if_true, if_false, NULL); | 3506 Split(cc, if_true, if_false, NULL); |
| 3507 __ bind(&slow_case); | 3507 __ bind(&slow_case); |
| 3508 } | 3508 } |
| 3509 CompareFlags flags = inline_smi_code | 3509 CompareFlags flags = inline_smi_code |
| 3510 ? NO_SMI_COMPARE_IN_STUB | 3510 ? NO_SMI_COMPARE_IN_STUB |
| 3511 : NO_COMPARE_FLAGS; | 3511 : NO_COMPARE_FLAGS; |
| 3512 CompareStub stub(cc, strict, flags, r1, r0); | 3512 CompareStub stub(cc, strict, flags, r1, r0); |
| 3513 __ CallStub(&stub); | 3513 __ CallStub(&stub); |
| 3514 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3514 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3616 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3616 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 3617 __ add(pc, r1, Operand(masm_->CodeObject())); | 3617 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 3618 } | 3618 } |
| 3619 | 3619 |
| 3620 | 3620 |
| 3621 #undef __ | 3621 #undef __ |
| 3622 | 3622 |
| 3623 } } // namespace v8::internal | 3623 } } // namespace v8::internal |
| 3624 | 3624 |
| 3625 #endif // V8_TARGET_ARCH_ARM | 3625 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |