OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 } | 392 } |
393 | 393 |
394 | 394 |
395 void CompareIC::Clear(Address address, Code* target) { | 395 void CompareIC::Clear(Address address, Code* target) { |
396 ASSERT(target->major_key() == CodeStub::CompareIC); | 396 ASSERT(target->major_key() == CodeStub::CompareIC); |
397 CompareIC::State handler_state; | 397 CompareIC::State handler_state; |
398 Token::Value op; | 398 Token::Value op; |
399 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, | 399 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, |
400 &handler_state, &op); | 400 &handler_state, &op); |
401 // Only clear CompareICs that can retain objects. | 401 // Only clear CompareICs that can retain objects. |
402 if (handler_state != KNOWN_OBJECTS) return; | 402 if (handler_state != KNOWN_OBJECT) return; |
403 SetTargetAtAddress(address, GetRawUninitialized(op)); | 403 SetTargetAtAddress(address, GetRawUninitialized(op)); |
404 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); | 404 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); |
405 } | 405 } |
406 | 406 |
407 | 407 |
408 static bool HasInterceptorGetter(JSObject* object) { | 408 static bool HasInterceptorGetter(JSObject* object) { |
409 return !object->GetNamedInterceptor()->getter()->IsUndefined(); | 409 return !object->GetNamedInterceptor()->getter()->IsUndefined(); |
410 } | 410 } |
411 | 411 |
412 | 412 |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 | 2031 |
2032 void UnaryOpIC::patch(Code* code) { | 2032 void UnaryOpIC::patch(Code* code) { |
2033 set_target(code); | 2033 set_target(code); |
2034 } | 2034 } |
2035 | 2035 |
2036 | 2036 |
2037 const char* UnaryOpIC::GetName(TypeInfo type_info) { | 2037 const char* UnaryOpIC::GetName(TypeInfo type_info) { |
2038 switch (type_info) { | 2038 switch (type_info) { |
2039 case UNINITIALIZED: return "Uninitialized"; | 2039 case UNINITIALIZED: return "Uninitialized"; |
2040 case SMI: return "Smi"; | 2040 case SMI: return "Smi"; |
2041 case HEAP_NUMBER: return "HeapNumbers"; | 2041 case NUMBER: return "Number"; |
2042 case GENERIC: return "Generic"; | 2042 case GENERIC: return "Generic"; |
2043 default: return "Invalid"; | 2043 default: return "Invalid"; |
2044 } | 2044 } |
2045 } | 2045 } |
2046 | 2046 |
2047 | 2047 |
2048 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) { | 2048 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) { |
2049 switch (type_info) { | 2049 switch (type_info) { |
2050 case UNINITIALIZED: | 2050 case UNINITIALIZED: |
2051 return ::v8::internal::UNINITIALIZED; | 2051 return ::v8::internal::UNINITIALIZED; |
2052 case SMI: | 2052 case SMI: |
2053 case HEAP_NUMBER: | 2053 case NUMBER: |
2054 return MONOMORPHIC; | 2054 return MONOMORPHIC; |
2055 case GENERIC: | 2055 case GENERIC: |
2056 return ::v8::internal::GENERIC; | 2056 return ::v8::internal::GENERIC; |
2057 } | 2057 } |
2058 UNREACHABLE(); | 2058 UNREACHABLE(); |
2059 return ::v8::internal::UNINITIALIZED; | 2059 return ::v8::internal::UNINITIALIZED; |
2060 } | 2060 } |
2061 | 2061 |
2062 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) { | 2062 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) { |
2063 ::v8::internal::TypeInfo operand_type = | 2063 ::v8::internal::TypeInfo operand_type = |
2064 ::v8::internal::TypeInfo::TypeFromValue(operand); | 2064 ::v8::internal::TypeInfo::TypeFromValue(operand); |
2065 if (operand_type.IsSmi()) { | 2065 if (operand_type.IsSmi()) { |
2066 return SMI; | 2066 return SMI; |
2067 } else if (operand_type.IsNumber()) { | 2067 } else if (operand_type.IsNumber()) { |
2068 return HEAP_NUMBER; | 2068 return NUMBER; |
2069 } else { | 2069 } else { |
2070 return GENERIC; | 2070 return GENERIC; |
2071 } | 2071 } |
2072 } | 2072 } |
2073 | 2073 |
2074 | 2074 |
2075 UnaryOpIC::TypeInfo UnaryOpIC::ComputeNewType( | 2075 UnaryOpIC::TypeInfo UnaryOpIC::ComputeNewType( |
2076 UnaryOpIC::TypeInfo current_type, | 2076 TypeInfo current_type, |
2077 UnaryOpIC::TypeInfo previous_type) { | 2077 TypeInfo previous_type) { |
2078 switch (previous_type) { | 2078 switch (previous_type) { |
2079 case UnaryOpIC::UNINITIALIZED: | 2079 case UNINITIALIZED: |
2080 return current_type; | 2080 return current_type; |
2081 case UnaryOpIC::SMI: | 2081 case SMI: |
2082 return (current_type == UnaryOpIC::GENERIC) | 2082 return (current_type == GENERIC) ? GENERIC : NUMBER; |
2083 ? UnaryOpIC::GENERIC | 2083 case NUMBER: |
2084 : UnaryOpIC::HEAP_NUMBER; | 2084 return GENERIC; |
2085 case UnaryOpIC::HEAP_NUMBER: | 2085 case GENERIC: |
2086 return UnaryOpIC::GENERIC; | |
2087 case UnaryOpIC::GENERIC: | |
2088 // We should never do patching if we are in GENERIC state. | 2086 // We should never do patching if we are in GENERIC state. |
2089 UNREACHABLE(); | 2087 UNREACHABLE(); |
2090 return UnaryOpIC::GENERIC; | 2088 return GENERIC; |
2091 } | 2089 } |
2092 UNREACHABLE(); | 2090 UNREACHABLE(); |
2093 return UnaryOpIC::GENERIC; | 2091 return GENERIC; |
2094 } | 2092 } |
2095 | 2093 |
2096 | 2094 |
2097 void BinaryOpIC::patch(Code* code) { | 2095 void BinaryOpIC::patch(Code* code) { |
2098 set_target(code); | 2096 set_target(code); |
2099 } | 2097 } |
2100 | 2098 |
2101 | 2099 |
2102 const char* BinaryOpIC::GetName(TypeInfo type_info) { | 2100 const char* BinaryOpIC::GetName(TypeInfo type_info) { |
2103 switch (type_info) { | 2101 switch (type_info) { |
2104 case UNINITIALIZED: return "Uninitialized"; | 2102 case UNINITIALIZED: return "Uninitialized"; |
2105 case SMI: return "SMI"; | 2103 case SMI: return "Smi"; |
2106 case INT32: return "Int32"; | 2104 case INT32: return "Int32"; |
2107 case HEAP_NUMBER: return "HeapNumber"; | 2105 case NUMBER: return "Number"; |
2108 case ODDBALL: return "Oddball"; | 2106 case ODDBALL: return "Oddball"; |
2109 case STRING: return "String"; | 2107 case STRING: return "String"; |
2110 case GENERIC: return "Generic"; | 2108 case GENERIC: return "Generic"; |
2111 default: return "Invalid"; | 2109 default: return "Invalid"; |
2112 } | 2110 } |
2113 } | 2111 } |
2114 | 2112 |
2115 | 2113 |
2116 BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) { | 2114 BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) { |
2117 switch (type_info) { | 2115 switch (type_info) { |
2118 case UNINITIALIZED: | 2116 case UNINITIALIZED: |
2119 return ::v8::internal::UNINITIALIZED; | 2117 return ::v8::internal::UNINITIALIZED; |
2120 case SMI: | 2118 case SMI: |
2121 case INT32: | 2119 case INT32: |
2122 case HEAP_NUMBER: | 2120 case NUMBER: |
2123 case ODDBALL: | 2121 case ODDBALL: |
2124 case STRING: | 2122 case STRING: |
2125 return MONOMORPHIC; | 2123 return MONOMORPHIC; |
2126 case GENERIC: | 2124 case GENERIC: |
2127 return ::v8::internal::GENERIC; | 2125 return ::v8::internal::GENERIC; |
2128 } | 2126 } |
2129 UNREACHABLE(); | 2127 UNREACHABLE(); |
2130 return ::v8::internal::UNINITIALIZED; | 2128 return ::v8::internal::UNINITIALIZED; |
2131 } | 2129 } |
2132 | 2130 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2188 | 2186 |
2189 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, | 2187 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, |
2190 Token::Value op) { | 2188 Token::Value op) { |
2191 ::v8::internal::TypeInfo type = | 2189 ::v8::internal::TypeInfo type = |
2192 ::v8::internal::TypeInfo::TypeFromValue(value); | 2190 ::v8::internal::TypeInfo::TypeFromValue(value); |
2193 if (type.IsSmi()) return BinaryOpIC::SMI; | 2191 if (type.IsSmi()) return BinaryOpIC::SMI; |
2194 if (type.IsInteger32()) { | 2192 if (type.IsInteger32()) { |
2195 if (kSmiValueSize == 32) return BinaryOpIC::SMI; | 2193 if (kSmiValueSize == 32) return BinaryOpIC::SMI; |
2196 return BinaryOpIC::INT32; | 2194 return BinaryOpIC::INT32; |
2197 } | 2195 } |
2198 if (type.IsNumber()) return BinaryOpIC::HEAP_NUMBER; | 2196 if (type.IsNumber()) return BinaryOpIC::NUMBER; |
2199 if (type.IsString()) return BinaryOpIC::STRING; | 2197 if (type.IsString()) return BinaryOpIC::STRING; |
2200 if (value->IsUndefined()) { | 2198 if (value->IsUndefined()) { |
2201 if (op == Token::BIT_AND || | 2199 if (op == Token::BIT_AND || |
2202 op == Token::BIT_OR || | 2200 op == Token::BIT_OR || |
2203 op == Token::BIT_XOR || | 2201 op == Token::BIT_XOR || |
2204 op == Token::SAR || | 2202 op == Token::SAR || |
2205 op == Token::SHL || | 2203 op == Token::SHL || |
2206 op == Token::SHR) { | 2204 op == Token::SHR) { |
2207 if (kSmiValueSize == 32) return BinaryOpIC::SMI; | 2205 if (kSmiValueSize == 32) return BinaryOpIC::SMI; |
2208 return BinaryOpIC::INT32; | 2206 return BinaryOpIC::INT32; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 | 2250 |
2253 if (new_overall == BinaryOpIC::SMI && previous_overall == BinaryOpIC::SMI) { | 2251 if (new_overall == BinaryOpIC::SMI && previous_overall == BinaryOpIC::SMI) { |
2254 if (op == Token::DIV || | 2252 if (op == Token::DIV || |
2255 op == Token::MUL || | 2253 op == Token::MUL || |
2256 op == Token::SHR || | 2254 op == Token::SHR || |
2257 kSmiValueSize == 32) { | 2255 kSmiValueSize == 32) { |
2258 // Arithmetic on two Smi inputs has yielded a heap number. | 2256 // Arithmetic on two Smi inputs has yielded a heap number. |
2259 // That is the only way to get here from the Smi stub. | 2257 // That is the only way to get here from the Smi stub. |
2260 // With 32-bit Smis, all overflows give heap numbers, but with | 2258 // With 32-bit Smis, all overflows give heap numbers, but with |
2261 // 31-bit Smis, most operations overflow to int32 results. | 2259 // 31-bit Smis, most operations overflow to int32 results. |
2262 result_type = BinaryOpIC::HEAP_NUMBER; | 2260 result_type = BinaryOpIC::NUMBER; |
2263 } else { | 2261 } else { |
2264 // Other operations on SMIs that overflow yield int32s. | 2262 // Other operations on SMIs that overflow yield int32s. |
2265 result_type = BinaryOpIC::INT32; | 2263 result_type = BinaryOpIC::INT32; |
2266 } | 2264 } |
2267 } | 2265 } |
2268 if (new_overall == BinaryOpIC::INT32 && | 2266 if (new_overall == BinaryOpIC::INT32 && |
2269 previous_overall == BinaryOpIC::INT32) { | 2267 previous_overall == BinaryOpIC::INT32) { |
2270 if (new_left == previous_left && new_right == previous_right) { | 2268 if (new_left == previous_left && new_right == previous_right) { |
2271 result_type = BinaryOpIC::HEAP_NUMBER; | 2269 result_type = BinaryOpIC::NUMBER; |
2272 } | 2270 } |
2273 } | 2271 } |
2274 | 2272 |
2275 BinaryOpStub stub(key, new_left, new_right, result_type); | 2273 BinaryOpStub stub(key, new_left, new_right, result_type); |
2276 Handle<Code> code = stub.GetCode(); | 2274 Handle<Code> code = stub.GetCode(); |
2277 if (!code.is_null()) { | 2275 if (!code.is_null()) { |
2278 #ifdef DEBUG | 2276 #ifdef DEBUG |
2279 if (FLAG_trace_ic) { | 2277 if (FLAG_trace_ic) { |
2280 PrintF("[BinaryOpIC in "); | 2278 PrintF("[BinaryOpIC in "); |
2281 JavaScriptFrame::PrintTop(stdout, false, true); | 2279 JavaScriptFrame::PrintTop(stdout, false, true); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2366 Handle<Code> CompareIC::GetUninitialized(Token::Value op) { | 2364 Handle<Code> CompareIC::GetUninitialized(Token::Value op) { |
2367 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); | 2365 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); |
2368 return stub.GetCode(); | 2366 return stub.GetCode(); |
2369 } | 2367 } |
2370 | 2368 |
2371 | 2369 |
2372 const char* CompareIC::GetStateName(State state) { | 2370 const char* CompareIC::GetStateName(State state) { |
2373 switch (state) { | 2371 switch (state) { |
2374 case UNINITIALIZED: return "UNINITIALIZED"; | 2372 case UNINITIALIZED: return "UNINITIALIZED"; |
2375 case SMI: return "SMI"; | 2373 case SMI: return "SMI"; |
2376 case HEAP_NUMBER: return "HEAP_NUMBER"; | 2374 case NUMBER: return "NUMBER"; |
2377 case OBJECT: return "OBJECTS"; | |
2378 case KNOWN_OBJECTS: return "KNOWN_OBJECTS"; | |
2379 case SYMBOL: return "SYMBOL"; | 2375 case SYMBOL: return "SYMBOL"; |
2380 case STRING: return "STRING"; | 2376 case STRING: return "STRING"; |
| 2377 case OBJECT: return "OBJECT"; |
| 2378 case KNOWN_OBJECT: return "KNOWN_OBJECT"; |
2381 case GENERIC: return "GENERIC"; | 2379 case GENERIC: return "GENERIC"; |
2382 default: | 2380 default: |
2383 UNREACHABLE(); | 2381 UNREACHABLE(); |
2384 return NULL; | 2382 return NULL; |
2385 } | 2383 } |
2386 } | 2384 } |
2387 | 2385 |
2388 | 2386 |
2389 static CompareIC::State InputState(CompareIC::State old_state, | 2387 static CompareIC::State InputState(CompareIC::State old_state, |
2390 Handle<Object> value) { | 2388 Handle<Object> value) { |
2391 switch (old_state) { | 2389 switch (old_state) { |
2392 case CompareIC::UNINITIALIZED: | 2390 case CompareIC::UNINITIALIZED: |
2393 if (value->IsSmi()) return CompareIC::SMI; | 2391 if (value->IsSmi()) return CompareIC::SMI; |
2394 if (value->IsHeapNumber()) return CompareIC::HEAP_NUMBER; | 2392 if (value->IsHeapNumber()) return CompareIC::NUMBER; |
2395 if (value->IsSymbol()) return CompareIC::SYMBOL; | 2393 if (value->IsSymbol()) return CompareIC::SYMBOL; |
2396 if (value->IsString()) return CompareIC::STRING; | 2394 if (value->IsString()) return CompareIC::STRING; |
2397 if (value->IsJSObject()) return CompareIC::OBJECT; | 2395 if (value->IsJSObject()) return CompareIC::OBJECT; |
2398 break; | 2396 break; |
2399 case CompareIC::SMI: | 2397 case CompareIC::SMI: |
2400 if (value->IsSmi()) return CompareIC::SMI; | 2398 if (value->IsSmi()) return CompareIC::SMI; |
2401 if (value->IsHeapNumber()) return CompareIC::HEAP_NUMBER; | 2399 if (value->IsHeapNumber()) return CompareIC::NUMBER; |
2402 break; | 2400 break; |
2403 case CompareIC::HEAP_NUMBER: | 2401 case CompareIC::NUMBER: |
2404 if (value->IsNumber()) return CompareIC::HEAP_NUMBER; | 2402 if (value->IsNumber()) return CompareIC::NUMBER; |
2405 break; | 2403 break; |
2406 case CompareIC::SYMBOL: | 2404 case CompareIC::SYMBOL: |
2407 if (value->IsSymbol()) return CompareIC::SYMBOL; | 2405 if (value->IsSymbol()) return CompareIC::SYMBOL; |
2408 if (value->IsString()) return CompareIC::STRING; | 2406 if (value->IsString()) return CompareIC::STRING; |
2409 break; | 2407 break; |
2410 case CompareIC::STRING: | 2408 case CompareIC::STRING: |
2411 if (value->IsSymbol() || value->IsString()) return CompareIC::STRING; | 2409 if (value->IsSymbol() || value->IsString()) return CompareIC::STRING; |
2412 break; | 2410 break; |
2413 case CompareIC::OBJECT: | 2411 case CompareIC::OBJECT: |
2414 if (value->IsJSObject()) return CompareIC::OBJECT; | 2412 if (value->IsJSObject()) return CompareIC::OBJECT; |
2415 break; | 2413 break; |
2416 case CompareIC::GENERIC: | 2414 case CompareIC::GENERIC: |
2417 break; | 2415 break; |
2418 case CompareIC::KNOWN_OBJECTS: | 2416 case CompareIC::KNOWN_OBJECT: |
2419 UNREACHABLE(); | 2417 UNREACHABLE(); |
2420 break; | 2418 break; |
2421 } | 2419 } |
2422 return CompareIC::GENERIC; | 2420 return CompareIC::GENERIC; |
2423 } | 2421 } |
2424 | 2422 |
2425 | 2423 |
2426 CompareIC::State CompareIC::TargetState(State old_state, | 2424 CompareIC::State CompareIC::TargetState(State old_state, |
2427 State old_left, | 2425 State old_left, |
2428 State old_right, | 2426 State old_right, |
2429 bool has_inlined_smi_code, | 2427 bool has_inlined_smi_code, |
2430 Handle<Object> x, | 2428 Handle<Object> x, |
2431 Handle<Object> y) { | 2429 Handle<Object> y) { |
2432 switch (old_state) { | 2430 switch (old_state) { |
2433 case UNINITIALIZED: | 2431 case UNINITIALIZED: |
2434 if (x->IsSmi() && y->IsSmi()) return SMI; | 2432 if (x->IsSmi() && y->IsSmi()) return SMI; |
2435 if (x->IsNumber() && y->IsNumber()) return HEAP_NUMBER; | 2433 if (x->IsNumber() && y->IsNumber()) return NUMBER; |
2436 if (Token::IsOrderedRelationalCompareOp(op_)) { | 2434 if (Token::IsOrderedRelationalCompareOp(op_)) { |
2437 // Ordered comparisons treat undefined as NaN, so the | 2435 // Ordered comparisons treat undefined as NaN, so the |
2438 // HEAP_NUMBER stub will do the right thing. | 2436 // NUMBER stub will do the right thing. |
2439 if ((x->IsNumber() && y->IsUndefined()) || | 2437 if ((x->IsNumber() && y->IsUndefined()) || |
2440 (y->IsNumber() && x->IsUndefined())) { | 2438 (y->IsNumber() && x->IsUndefined())) { |
2441 return HEAP_NUMBER; | 2439 return NUMBER; |
2442 } | 2440 } |
2443 } | 2441 } |
2444 if (x->IsSymbol() && y->IsSymbol()) { | 2442 if (x->IsSymbol() && y->IsSymbol()) { |
2445 // We compare symbols as strings if we need to determine | 2443 // We compare symbols as strings if we need to determine |
2446 // the order in a non-equality compare. | 2444 // the order in a non-equality compare. |
2447 return Token::IsEqualityOp(op_) ? SYMBOL : STRING; | 2445 return Token::IsEqualityOp(op_) ? SYMBOL : STRING; |
2448 } | 2446 } |
2449 if (x->IsString() && y->IsString()) return STRING; | 2447 if (x->IsString() && y->IsString()) return STRING; |
2450 if (!Token::IsEqualityOp(op_)) return GENERIC; | 2448 if (!Token::IsEqualityOp(op_)) return GENERIC; |
2451 if (x->IsJSObject() && y->IsJSObject()) { | 2449 if (x->IsJSObject() && y->IsJSObject()) { |
2452 if (Handle<JSObject>::cast(x)->map() == | 2450 if (Handle<JSObject>::cast(x)->map() == |
2453 Handle<JSObject>::cast(y)->map() && | 2451 Handle<JSObject>::cast(y)->map()) { |
2454 Token::IsEqualityOp(op_)) { | 2452 return KNOWN_OBJECT; |
2455 return KNOWN_OBJECTS; | |
2456 } else { | 2453 } else { |
2457 return OBJECT; | 2454 return OBJECT; |
2458 } | 2455 } |
2459 } | 2456 } |
2460 return GENERIC; | 2457 return GENERIC; |
2461 case SMI: | 2458 case SMI: |
2462 return x->IsNumber() && y->IsNumber() | 2459 return x->IsNumber() && y->IsNumber() ? NUMBER : GENERIC; |
2463 ? HEAP_NUMBER | |
2464 : GENERIC; | |
2465 case SYMBOL: | 2460 case SYMBOL: |
2466 ASSERT(Token::IsEqualityOp(op_)); | 2461 ASSERT(Token::IsEqualityOp(op_)); |
2467 return x->IsString() && y->IsString() ? STRING : GENERIC; | 2462 return x->IsString() && y->IsString() ? STRING : GENERIC; |
2468 case HEAP_NUMBER: | 2463 case NUMBER: |
2469 if (old_left == SMI && x->IsHeapNumber()) return HEAP_NUMBER; | 2464 // If the failure was due to one side changing from smi to heap number, |
2470 if (old_right == SMI && y->IsHeapNumber()) return HEAP_NUMBER; | 2465 // then keep the state (if other changed at the same time, we will get |
| 2466 // a second miss and then go to generic). |
| 2467 if (old_left == SMI && x->IsHeapNumber()) return NUMBER; |
| 2468 if (old_right == SMI && y->IsHeapNumber()) return NUMBER; |
| 2469 return GENERIC; |
| 2470 case KNOWN_OBJECT: |
| 2471 ASSERT(Token::IsEqualityOp(op_)); |
| 2472 if (x->IsJSObject() && y->IsJSObject()) return OBJECT; |
| 2473 return GENERIC; |
2471 case STRING: | 2474 case STRING: |
2472 case OBJECT: | 2475 case OBJECT: |
2473 case KNOWN_OBJECTS: | |
2474 case GENERIC: | 2476 case GENERIC: |
2475 return GENERIC; | 2477 return GENERIC; |
2476 } | 2478 } |
2477 UNREACHABLE(); | 2479 UNREACHABLE(); |
2478 return GENERIC; // Make the compiler happy. | 2480 return GENERIC; // Make the compiler happy. |
2479 } | 2481 } |
2480 | 2482 |
2481 | 2483 |
2482 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { | 2484 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
2483 HandleScope scope; | 2485 HandleScope scope; |
2484 State previous_left, previous_right, previous_state; | 2486 State previous_left, previous_right, previous_state; |
2485 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, | 2487 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, |
2486 &previous_right, &previous_state, NULL); | 2488 &previous_right, &previous_state, NULL); |
2487 State new_left = InputState(previous_left, x); | 2489 State new_left = InputState(previous_left, x); |
2488 State new_right = InputState(previous_right, y); | 2490 State new_right = InputState(previous_right, y); |
2489 State state = TargetState(previous_state, previous_left, previous_right, | 2491 State state = TargetState(previous_state, previous_left, previous_right, |
2490 HasInlinedSmiCode(address()), x, y); | 2492 HasInlinedSmiCode(address()), x, y); |
2491 ICCompareStub stub(op_, new_left, new_right, state); | 2493 ICCompareStub stub(op_, new_left, new_right, state); |
2492 if (state == KNOWN_OBJECTS) { | 2494 if (state == KNOWN_OBJECT) { |
2493 stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map())); | 2495 stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map())); |
2494 } | 2496 } |
2495 set_target(*stub.GetCode()); | 2497 set_target(*stub.GetCode()); |
2496 | 2498 |
2497 #ifdef DEBUG | 2499 #ifdef DEBUG |
2498 if (FLAG_trace_ic) { | 2500 if (FLAG_trace_ic) { |
2499 PrintF("[CompareIC in "); | 2501 PrintF("[CompareIC in "); |
2500 JavaScriptFrame::PrintTop(stdout, false, true); | 2502 JavaScriptFrame::PrintTop(stdout, false, true); |
2501 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", | 2503 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", |
2502 GetStateName(previous_left), | 2504 GetStateName(previous_left), |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2559 #undef ADDR | 2561 #undef ADDR |
2560 }; | 2562 }; |
2561 | 2563 |
2562 | 2564 |
2563 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2565 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2564 return IC_utilities[id]; | 2566 return IC_utilities[id]; |
2565 } | 2567 } |
2566 | 2568 |
2567 | 2569 |
2568 } } // namespace v8::internal | 2570 } } // namespace v8::internal |
OLD | NEW |