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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 | 299 |
300 switch (target->kind()) { | 300 switch (target->kind()) { |
301 case Code::LOAD_IC: return LoadIC::Clear(address, target); | 301 case Code::LOAD_IC: return LoadIC::Clear(address, target); |
302 case Code::KEYED_LOAD_IC: | 302 case Code::KEYED_LOAD_IC: |
303 return KeyedLoadIC::Clear(address, target); | 303 return KeyedLoadIC::Clear(address, target); |
304 case Code::STORE_IC: return StoreIC::Clear(address, target); | 304 case Code::STORE_IC: return StoreIC::Clear(address, target); |
305 case Code::KEYED_STORE_IC: | 305 case Code::KEYED_STORE_IC: |
306 return KeyedStoreIC::Clear(address, target); | 306 return KeyedStoreIC::Clear(address, target); |
307 case Code::CALL_IC: return CallIC::Clear(address, target); | 307 case Code::CALL_IC: return CallIC::Clear(address, target); |
308 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); | 308 case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); |
309 case Code::TYPE_RECORDING_UNARY_OP_IC: | 309 case Code::UNARY_OP_IC: |
310 case Code::TYPE_RECORDING_BINARY_OP_IC: | 310 case Code::BINARY_OP_IC: |
311 case Code::COMPARE_IC: | 311 case Code::COMPARE_IC: |
312 // Clearing these is tricky and does not | 312 // Clearing these is tricky and does not |
313 // make any performance difference. | 313 // make any performance difference. |
314 return; | 314 return; |
315 default: UNREACHABLE(); | 315 default: UNREACHABLE(); |
316 } | 316 } |
317 } | 317 } |
318 | 318 |
319 | 319 |
320 void CallICBase::Clear(Address address, Code* target) { | 320 void CallICBase::Clear(Address address, Code* target) { |
(...skipping 1829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2150 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2150 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
2151 return ic.Store(state, | 2151 return ic.Store(state, |
2152 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), | 2152 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), |
2153 args.at<Object>(0), | 2153 args.at<Object>(0), |
2154 args.at<Object>(1), | 2154 args.at<Object>(1), |
2155 args.at<Object>(2), | 2155 args.at<Object>(2), |
2156 true); | 2156 true); |
2157 } | 2157 } |
2158 | 2158 |
2159 | 2159 |
2160 void TRUnaryOpIC::patch(Code* code) { | 2160 void UnaryOpIC::patch(Code* code) { |
2161 set_target(code); | 2161 set_target(code); |
2162 } | 2162 } |
2163 | 2163 |
2164 | 2164 |
2165 const char* TRUnaryOpIC::GetName(TypeInfo type_info) { | 2165 const char* UnaryOpIC::GetName(TypeInfo type_info) { |
2166 switch (type_info) { | 2166 switch (type_info) { |
2167 case UNINITIALIZED: return "Uninitialized"; | 2167 case UNINITIALIZED: return "Uninitialized"; |
2168 case SMI: return "Smi"; | 2168 case SMI: return "Smi"; |
2169 case HEAP_NUMBER: return "HeapNumbers"; | 2169 case HEAP_NUMBER: return "HeapNumbers"; |
2170 case GENERIC: return "Generic"; | 2170 case GENERIC: return "Generic"; |
2171 default: return "Invalid"; | 2171 default: return "Invalid"; |
2172 } | 2172 } |
2173 } | 2173 } |
2174 | 2174 |
2175 | 2175 |
2176 TRUnaryOpIC::State TRUnaryOpIC::ToState(TypeInfo type_info) { | 2176 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) { |
2177 switch (type_info) { | 2177 switch (type_info) { |
2178 case UNINITIALIZED: | 2178 case UNINITIALIZED: |
2179 return ::v8::internal::UNINITIALIZED; | 2179 return ::v8::internal::UNINITIALIZED; |
2180 case SMI: | 2180 case SMI: |
2181 case HEAP_NUMBER: | 2181 case HEAP_NUMBER: |
2182 return MONOMORPHIC; | 2182 return MONOMORPHIC; |
2183 case GENERIC: | 2183 case GENERIC: |
2184 return MEGAMORPHIC; | 2184 return MEGAMORPHIC; |
2185 } | 2185 } |
2186 UNREACHABLE(); | 2186 UNREACHABLE(); |
2187 return ::v8::internal::UNINITIALIZED; | 2187 return ::v8::internal::UNINITIALIZED; |
2188 } | 2188 } |
2189 | 2189 |
2190 TRUnaryOpIC::TypeInfo TRUnaryOpIC::GetTypeInfo(Handle<Object> operand) { | 2190 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) { |
2191 ::v8::internal::TypeInfo operand_type = | 2191 ::v8::internal::TypeInfo operand_type = |
2192 ::v8::internal::TypeInfo::TypeFromValue(operand); | 2192 ::v8::internal::TypeInfo::TypeFromValue(operand); |
2193 if (operand_type.IsSmi()) { | 2193 if (operand_type.IsSmi()) { |
2194 return SMI; | 2194 return SMI; |
2195 } else if (operand_type.IsNumber()) { | 2195 } else if (operand_type.IsNumber()) { |
2196 return HEAP_NUMBER; | 2196 return HEAP_NUMBER; |
2197 } else { | 2197 } else { |
2198 return GENERIC; | 2198 return GENERIC; |
2199 } | 2199 } |
2200 } | 2200 } |
2201 | 2201 |
2202 | 2202 |
2203 TRUnaryOpIC::TypeInfo TRUnaryOpIC::ComputeNewType( | 2203 UnaryOpIC::TypeInfo UnaryOpIC::ComputeNewType( |
2204 TRUnaryOpIC::TypeInfo type, | 2204 UnaryOpIC::TypeInfo current_type, |
2205 TRUnaryOpIC::TypeInfo previous) { | 2205 UnaryOpIC::TypeInfo previous_type) { |
2206 switch (previous) { | 2206 switch (previous_type) { |
2207 case TRUnaryOpIC::UNINITIALIZED: | 2207 case UnaryOpIC::UNINITIALIZED: |
2208 return type; | 2208 return current_type; |
2209 case TRUnaryOpIC::SMI: | 2209 case UnaryOpIC::SMI: |
2210 return (type == TRUnaryOpIC::GENERIC) | 2210 return (current_type == UnaryOpIC::GENERIC) |
2211 ? TRUnaryOpIC::GENERIC | 2211 ? UnaryOpIC::GENERIC |
2212 : TRUnaryOpIC::HEAP_NUMBER; | 2212 : UnaryOpIC::HEAP_NUMBER; |
2213 case TRUnaryOpIC::HEAP_NUMBER: | 2213 case UnaryOpIC::HEAP_NUMBER: |
2214 return TRUnaryOpIC::GENERIC; | 2214 return UnaryOpIC::GENERIC; |
2215 case TRUnaryOpIC::GENERIC: | 2215 case UnaryOpIC::GENERIC: |
2216 // We should never do patching if we are in GENERIC state. | 2216 // We should never do patching if we are in GENERIC state. |
2217 UNREACHABLE(); | 2217 UNREACHABLE(); |
2218 return TRUnaryOpIC::GENERIC; | 2218 return UnaryOpIC::GENERIC; |
2219 } | 2219 } |
2220 UNREACHABLE(); | 2220 UNREACHABLE(); |
2221 return TRUnaryOpIC::GENERIC; | 2221 return UnaryOpIC::GENERIC; |
2222 } | 2222 } |
2223 | 2223 |
2224 | 2224 |
2225 void TRBinaryOpIC::patch(Code* code) { | 2225 void BinaryOpIC::patch(Code* code) { |
2226 set_target(code); | 2226 set_target(code); |
2227 } | 2227 } |
2228 | 2228 |
2229 | 2229 |
2230 const char* TRBinaryOpIC::GetName(TypeInfo type_info) { | 2230 const char* BinaryOpIC::GetName(TypeInfo type_info) { |
2231 switch (type_info) { | 2231 switch (type_info) { |
2232 case UNINITIALIZED: return "Uninitialized"; | 2232 case UNINITIALIZED: return "Uninitialized"; |
2233 case SMI: return "SMI"; | 2233 case SMI: return "SMI"; |
2234 case INT32: return "Int32s"; | 2234 case INT32: return "Int32s"; |
2235 case HEAP_NUMBER: return "HeapNumbers"; | 2235 case HEAP_NUMBER: return "HeapNumbers"; |
2236 case ODDBALL: return "Oddball"; | 2236 case ODDBALL: return "Oddball"; |
2237 case BOTH_STRING: return "BothStrings"; | 2237 case BOTH_STRING: return "BothStrings"; |
2238 case STRING: return "Strings"; | 2238 case STRING: return "Strings"; |
2239 case GENERIC: return "Generic"; | 2239 case GENERIC: return "Generic"; |
2240 default: return "Invalid"; | 2240 default: return "Invalid"; |
2241 } | 2241 } |
2242 } | 2242 } |
2243 | 2243 |
2244 | 2244 |
2245 TRBinaryOpIC::State TRBinaryOpIC::ToState(TypeInfo type_info) { | 2245 BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) { |
2246 switch (type_info) { | 2246 switch (type_info) { |
2247 case UNINITIALIZED: | 2247 case UNINITIALIZED: |
2248 return ::v8::internal::UNINITIALIZED; | 2248 return ::v8::internal::UNINITIALIZED; |
2249 case SMI: | 2249 case SMI: |
2250 case INT32: | 2250 case INT32: |
2251 case HEAP_NUMBER: | 2251 case HEAP_NUMBER: |
2252 case ODDBALL: | 2252 case ODDBALL: |
2253 case BOTH_STRING: | 2253 case BOTH_STRING: |
2254 case STRING: | 2254 case STRING: |
2255 return MONOMORPHIC; | 2255 return MONOMORPHIC; |
2256 case GENERIC: | 2256 case GENERIC: |
2257 return MEGAMORPHIC; | 2257 return MEGAMORPHIC; |
2258 } | 2258 } |
2259 UNREACHABLE(); | 2259 UNREACHABLE(); |
2260 return ::v8::internal::UNINITIALIZED; | 2260 return ::v8::internal::UNINITIALIZED; |
2261 } | 2261 } |
2262 | 2262 |
2263 | 2263 |
2264 TRBinaryOpIC::TypeInfo TRBinaryOpIC::JoinTypes(TRBinaryOpIC::TypeInfo x, | 2264 BinaryOpIC::TypeInfo BinaryOpIC::JoinTypes(BinaryOpIC::TypeInfo x, |
2265 TRBinaryOpIC::TypeInfo y) { | 2265 BinaryOpIC::TypeInfo y) { |
2266 if (x == UNINITIALIZED) return y; | 2266 if (x == UNINITIALIZED) return y; |
2267 if (y == UNINITIALIZED) return x; | 2267 if (y == UNINITIALIZED) return x; |
2268 if (x == y) return x; | 2268 if (x == y) return x; |
2269 if (x == BOTH_STRING && y == STRING) return STRING; | 2269 if (x == BOTH_STRING && y == STRING) return STRING; |
2270 if (x == STRING && y == BOTH_STRING) return STRING; | 2270 if (x == STRING && y == BOTH_STRING) return STRING; |
2271 if (x == STRING || x == BOTH_STRING || y == STRING || y == BOTH_STRING) { | 2271 if (x == STRING || x == BOTH_STRING || y == STRING || y == BOTH_STRING) { |
2272 return GENERIC; | 2272 return GENERIC; |
2273 } | 2273 } |
2274 if (x > y) return x; | 2274 if (x > y) return x; |
2275 return y; | 2275 return y; |
2276 } | 2276 } |
2277 | 2277 |
2278 | 2278 |
2279 TRBinaryOpIC::TypeInfo TRBinaryOpIC::GetTypeInfo(Handle<Object> left, | 2279 BinaryOpIC::TypeInfo BinaryOpIC::GetTypeInfo(Handle<Object> left, |
2280 Handle<Object> right) { | 2280 Handle<Object> right) { |
2281 ::v8::internal::TypeInfo left_type = | 2281 ::v8::internal::TypeInfo left_type = |
2282 ::v8::internal::TypeInfo::TypeFromValue(left); | 2282 ::v8::internal::TypeInfo::TypeFromValue(left); |
2283 ::v8::internal::TypeInfo right_type = | 2283 ::v8::internal::TypeInfo right_type = |
2284 ::v8::internal::TypeInfo::TypeFromValue(right); | 2284 ::v8::internal::TypeInfo::TypeFromValue(right); |
2285 | 2285 |
2286 if (left_type.IsSmi() && right_type.IsSmi()) { | 2286 if (left_type.IsSmi() && right_type.IsSmi()) { |
2287 return SMI; | 2287 return SMI; |
2288 } | 2288 } |
2289 | 2289 |
2290 if (left_type.IsInteger32() && right_type.IsInteger32()) { | 2290 if (left_type.IsInteger32() && right_type.IsInteger32()) { |
(...skipping 17 matching lines...) Expand all Loading... |
2308 // Check for oddball objects. | 2308 // Check for oddball objects. |
2309 if (left->IsUndefined() && right->IsNumber()) return ODDBALL; | 2309 if (left->IsUndefined() && right->IsNumber()) return ODDBALL; |
2310 if (left->IsNumber() && right->IsUndefined()) return ODDBALL; | 2310 if (left->IsNumber() && right->IsUndefined()) return ODDBALL; |
2311 | 2311 |
2312 return GENERIC; | 2312 return GENERIC; |
2313 } | 2313 } |
2314 | 2314 |
2315 | 2315 |
2316 // defined in code-stubs-<arch>.cc | 2316 // defined in code-stubs-<arch>.cc |
2317 // Only needed to remove dependency of ic.cc on code-stubs-<arch>.h. | 2317 // Only needed to remove dependency of ic.cc on code-stubs-<arch>.h. |
2318 Handle<Code> GetTypeRecordingUnaryOpStub(int key, | 2318 Handle<Code> GetUnaryOpStub(int key, UnaryOpIC::TypeInfo type_info); |
2319 TRUnaryOpIC::TypeInfo type_info); | |
2320 | 2319 |
2321 | 2320 |
2322 RUNTIME_FUNCTION(MaybeObject*, TypeRecordingUnaryOp_Patch) { | 2321 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) { |
2323 ASSERT(args.length() == 4); | 2322 ASSERT(args.length() == 4); |
2324 | 2323 |
2325 HandleScope scope(isolate); | 2324 HandleScope scope(isolate); |
2326 Handle<Object> operand = args.at<Object>(0); | 2325 Handle<Object> operand = args.at<Object>(0); |
2327 int key = Smi::cast(args[1])->value(); | 2326 int key = Smi::cast(args[1])->value(); |
2328 Token::Value op = static_cast<Token::Value>(Smi::cast(args[2])->value()); | 2327 Token::Value op = static_cast<Token::Value>(Smi::cast(args[2])->value()); |
2329 TRUnaryOpIC::TypeInfo previous_type = | 2328 UnaryOpIC::TypeInfo previous_type = |
2330 static_cast<TRUnaryOpIC::TypeInfo>(Smi::cast(args[3])->value()); | 2329 static_cast<UnaryOpIC::TypeInfo>(Smi::cast(args[3])->value()); |
2331 | 2330 |
2332 TRUnaryOpIC::TypeInfo type = TRUnaryOpIC::GetTypeInfo(operand); | 2331 UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand); |
2333 type = TRUnaryOpIC::ComputeNewType(type, previous_type); | 2332 type = UnaryOpIC::ComputeNewType(type, previous_type); |
2334 | 2333 |
2335 Handle<Code> code = GetTypeRecordingUnaryOpStub(key, type); | 2334 Handle<Code> code = GetUnaryOpStub(key, type); |
2336 if (!code.is_null()) { | 2335 if (!code.is_null()) { |
2337 if (FLAG_trace_ic) { | 2336 if (FLAG_trace_ic) { |
2338 PrintF("[TypeRecordingUnaryOpIC (%s->%s)#%s]\n", | 2337 PrintF("[UnaryOpIC (%s->%s)#%s]\n", |
2339 TRUnaryOpIC::GetName(previous_type), | 2338 UnaryOpIC::GetName(previous_type), |
2340 TRUnaryOpIC::GetName(type), | 2339 UnaryOpIC::GetName(type), |
2341 Token::Name(op)); | 2340 Token::Name(op)); |
2342 } | 2341 } |
2343 TRUnaryOpIC ic(isolate); | 2342 UnaryOpIC ic(isolate); |
2344 ic.patch(*code); | 2343 ic.patch(*code); |
2345 } | 2344 } |
2346 | 2345 |
2347 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( | 2346 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( |
2348 isolate->thread_local_top()->context_->builtins(), isolate); | 2347 isolate->thread_local_top()->context_->builtins(), isolate); |
2349 Object* builtin = NULL; // Initialization calms down the compiler. | 2348 Object* builtin = NULL; // Initialization calms down the compiler. |
2350 switch (op) { | 2349 switch (op) { |
2351 case Token::SUB: | 2350 case Token::SUB: |
2352 builtin = builtins->javascript_builtin(Builtins::UNARY_MINUS); | 2351 builtin = builtins->javascript_builtin(Builtins::UNARY_MINUS); |
2353 break; | 2352 break; |
(...skipping 10 matching lines...) Expand all Loading... |
2364 Handle<Object> result = Execution::Call(builtin_function, operand, 0, NULL, | 2363 Handle<Object> result = Execution::Call(builtin_function, operand, 0, NULL, |
2365 &caught_exception); | 2364 &caught_exception); |
2366 if (caught_exception) { | 2365 if (caught_exception) { |
2367 return Failure::Exception(); | 2366 return Failure::Exception(); |
2368 } | 2367 } |
2369 return *result; | 2368 return *result; |
2370 } | 2369 } |
2371 | 2370 |
2372 // defined in code-stubs-<arch>.cc | 2371 // defined in code-stubs-<arch>.cc |
2373 // Only needed to remove dependency of ic.cc on code-stubs-<arch>.h. | 2372 // Only needed to remove dependency of ic.cc on code-stubs-<arch>.h. |
2374 Handle<Code> GetTypeRecordingBinaryOpStub(int key, | 2373 Handle<Code> GetBinaryOpStub(int key, |
2375 TRBinaryOpIC::TypeInfo type_info, | 2374 BinaryOpIC::TypeInfo type_info, |
2376 TRBinaryOpIC::TypeInfo result_type); | 2375 BinaryOpIC::TypeInfo result_type); |
2377 | 2376 |
2378 | 2377 |
2379 RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) { | 2378 RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) { |
2380 ASSERT(args.length() == 5); | 2379 ASSERT(args.length() == 5); |
2381 | 2380 |
2382 HandleScope scope(isolate); | 2381 HandleScope scope(isolate); |
2383 Handle<Object> left = args.at<Object>(0); | 2382 Handle<Object> left = args.at<Object>(0); |
2384 Handle<Object> right = args.at<Object>(1); | 2383 Handle<Object> right = args.at<Object>(1); |
2385 int key = Smi::cast(args[2])->value(); | 2384 int key = Smi::cast(args[2])->value(); |
2386 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value()); | 2385 Token::Value op = static_cast<Token::Value>(Smi::cast(args[3])->value()); |
2387 TRBinaryOpIC::TypeInfo previous_type = | 2386 BinaryOpIC::TypeInfo previous_type = |
2388 static_cast<TRBinaryOpIC::TypeInfo>(Smi::cast(args[4])->value()); | 2387 static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[4])->value()); |
2389 | 2388 |
2390 TRBinaryOpIC::TypeInfo type = TRBinaryOpIC::GetTypeInfo(left, right); | 2389 BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(left, right); |
2391 type = TRBinaryOpIC::JoinTypes(type, previous_type); | 2390 type = BinaryOpIC::JoinTypes(type, previous_type); |
2392 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED; | 2391 BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED; |
2393 if ((type == TRBinaryOpIC::STRING || type == TRBinaryOpIC::BOTH_STRING) && | 2392 if ((type == BinaryOpIC::STRING || type == BinaryOpIC::BOTH_STRING) && |
2394 op != Token::ADD) { | 2393 op != Token::ADD) { |
2395 type = TRBinaryOpIC::GENERIC; | 2394 type = BinaryOpIC::GENERIC; |
2396 } | 2395 } |
2397 if (type == TRBinaryOpIC::SMI && previous_type == TRBinaryOpIC::SMI) { | 2396 if (type == BinaryOpIC::SMI && previous_type == BinaryOpIC::SMI) { |
2398 if (op == Token::DIV || | 2397 if (op == Token::DIV || |
2399 op == Token::MUL || | 2398 op == Token::MUL || |
2400 op == Token::SHR || | 2399 op == Token::SHR || |
2401 kSmiValueSize == 32) { | 2400 kSmiValueSize == 32) { |
2402 // Arithmetic on two Smi inputs has yielded a heap number. | 2401 // Arithmetic on two Smi inputs has yielded a heap number. |
2403 // That is the only way to get here from the Smi stub. | 2402 // That is the only way to get here from the Smi stub. |
2404 // With 32-bit Smis, all overflows give heap numbers, but with | 2403 // With 32-bit Smis, all overflows give heap numbers, but with |
2405 // 31-bit Smis, most operations overflow to int32 results. | 2404 // 31-bit Smis, most operations overflow to int32 results. |
2406 result_type = TRBinaryOpIC::HEAP_NUMBER; | 2405 result_type = BinaryOpIC::HEAP_NUMBER; |
2407 } else { | 2406 } else { |
2408 // Other operations on SMIs that overflow yield int32s. | 2407 // Other operations on SMIs that overflow yield int32s. |
2409 result_type = TRBinaryOpIC::INT32; | 2408 result_type = BinaryOpIC::INT32; |
2410 } | 2409 } |
2411 } | 2410 } |
2412 if (type == TRBinaryOpIC::INT32 && previous_type == TRBinaryOpIC::INT32) { | 2411 if (type == BinaryOpIC::INT32 && previous_type == BinaryOpIC::INT32) { |
2413 // We must be here because an operation on two INT32 types overflowed. | 2412 // We must be here because an operation on two INT32 types overflowed. |
2414 result_type = TRBinaryOpIC::HEAP_NUMBER; | 2413 result_type = BinaryOpIC::HEAP_NUMBER; |
2415 } | 2414 } |
2416 | 2415 |
2417 Handle<Code> code = GetTypeRecordingBinaryOpStub(key, type, result_type); | 2416 Handle<Code> code = GetBinaryOpStub(key, type, result_type); |
2418 if (!code.is_null()) { | 2417 if (!code.is_null()) { |
2419 if (FLAG_trace_ic) { | 2418 if (FLAG_trace_ic) { |
2420 PrintF("[TypeRecordingBinaryOpIC (%s->(%s->%s))#%s]\n", | 2419 PrintF("[BinaryOpIC (%s->(%s->%s))#%s]\n", |
2421 TRBinaryOpIC::GetName(previous_type), | 2420 BinaryOpIC::GetName(previous_type), |
2422 TRBinaryOpIC::GetName(type), | 2421 BinaryOpIC::GetName(type), |
2423 TRBinaryOpIC::GetName(result_type), | 2422 BinaryOpIC::GetName(result_type), |
2424 Token::Name(op)); | 2423 Token::Name(op)); |
2425 } | 2424 } |
2426 TRBinaryOpIC ic(isolate); | 2425 BinaryOpIC ic(isolate); |
2427 ic.patch(*code); | 2426 ic.patch(*code); |
2428 | 2427 |
2429 // Activate inlined smi code. | 2428 // Activate inlined smi code. |
2430 if (previous_type == TRBinaryOpIC::UNINITIALIZED) { | 2429 if (previous_type == BinaryOpIC::UNINITIALIZED) { |
2431 PatchInlinedSmiCode(ic.address()); | 2430 PatchInlinedSmiCode(ic.address()); |
2432 } | 2431 } |
2433 } | 2432 } |
2434 | 2433 |
2435 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( | 2434 Handle<JSBuiltinsObject> builtins = Handle<JSBuiltinsObject>( |
2436 isolate->thread_local_top()->context_->builtins(), isolate); | 2435 isolate->thread_local_top()->context_->builtins(), isolate); |
2437 Object* builtin = NULL; // Initialization calms down the compiler. | 2436 Object* builtin = NULL; // Initialization calms down the compiler. |
2438 switch (op) { | 2437 switch (op) { |
2439 case Token::ADD: | 2438 case Token::ADD: |
2440 builtin = builtins->javascript_builtin(Builtins::ADD); | 2439 builtin = builtins->javascript_builtin(Builtins::ADD); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2557 #undef ADDR | 2556 #undef ADDR |
2558 }; | 2557 }; |
2559 | 2558 |
2560 | 2559 |
2561 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2560 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2562 return IC_utilities[id]; | 2561 return IC_utilities[id]; |
2563 } | 2562 } |
2564 | 2563 |
2565 | 2564 |
2566 } } // namespace v8::internal | 2565 } } // namespace v8::internal |
OLD | NEW |