| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ic/ic.h" | 5 #include "src/ic/ic.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api-arguments-inl.h" | 8 #include "src/api-arguments-inl.h" |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 2219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2230 | 2230 |
| 2231 | 2231 |
| 2232 // ---------------------------------------------------------------------------- | 2232 // ---------------------------------------------------------------------------- |
| 2233 // Static IC stub generators. | 2233 // Static IC stub generators. |
| 2234 // | 2234 // |
| 2235 | 2235 |
| 2236 // Used from ic-<arch>.cc. | 2236 // Used from ic-<arch>.cc. |
| 2237 RUNTIME_FUNCTION(Runtime_CallIC_Miss) { | 2237 RUNTIME_FUNCTION(Runtime_CallIC_Miss) { |
| 2238 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2238 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2239 HandleScope scope(isolate); | 2239 HandleScope scope(isolate); |
| 2240 DCHECK(args.length() == 3); | 2240 DCHECK_EQ(3, args.length()); |
| 2241 // Runtime functions don't follow the IC's calling convention. |
| 2241 Handle<Object> function = args.at<Object>(0); | 2242 Handle<Object> function = args.at<Object>(0); |
| 2242 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1); | 2243 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1); |
| 2243 Handle<Smi> slot = args.at<Smi>(2); | 2244 Handle<Smi> slot = args.at<Smi>(2); |
| 2244 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2245 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2245 CallICNexus nexus(vector, vector_slot); | 2246 CallICNexus nexus(vector, vector_slot); |
| 2246 CallIC ic(isolate, &nexus); | 2247 CallIC ic(isolate, &nexus); |
| 2247 ic.HandleMiss(function); | 2248 ic.HandleMiss(function); |
| 2248 return *function; | 2249 return *function; |
| 2249 } | 2250 } |
| 2250 | 2251 |
| 2251 | 2252 |
| 2252 // Used from ic-<arch>.cc. | 2253 // Used from ic-<arch>.cc. |
| 2253 RUNTIME_FUNCTION(Runtime_LoadIC_Miss) { | 2254 RUNTIME_FUNCTION(Runtime_LoadIC_Miss) { |
| 2254 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2255 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2255 HandleScope scope(isolate); | 2256 HandleScope scope(isolate); |
| 2257 DCHECK_EQ(4, args.length()); |
| 2258 // Runtime functions don't follow the IC's calling convention. |
| 2256 Handle<Object> receiver = args.at<Object>(0); | 2259 Handle<Object> receiver = args.at<Object>(0); |
| 2257 | |
| 2258 DCHECK_EQ(4, args.length()); | |
| 2259 Handle<Smi> slot = args.at<Smi>(2); | 2260 Handle<Smi> slot = args.at<Smi>(2); |
| 2260 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); | 2261 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); |
| 2261 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2262 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2262 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the | 2263 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the |
| 2263 // LoadIC miss handler if the handler misses. Since the vector Nexus is | 2264 // LoadIC miss handler if the handler misses. Since the vector Nexus is |
| 2264 // set up outside the IC, handle that here. | 2265 // set up outside the IC, handle that here. |
| 2265 FeedbackVectorSlotKind kind = vector->GetKind(vector_slot); | 2266 FeedbackVectorSlotKind kind = vector->GetKind(vector_slot); |
| 2266 if (kind == FeedbackVectorSlotKind::LOAD_IC) { | 2267 if (kind == FeedbackVectorSlotKind::LOAD_IC) { |
| 2267 Handle<Name> key = args.at<Name>(1); | 2268 Handle<Name> key = args.at<Name>(1); |
| 2268 LoadICNexus nexus(vector, vector_slot); | 2269 LoadICNexus nexus(vector, vector_slot); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2287 ic.UpdateState(receiver, key); | 2288 ic.UpdateState(receiver, key); |
| 2288 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2289 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
| 2289 } | 2290 } |
| 2290 } | 2291 } |
| 2291 | 2292 |
| 2292 // Used from ic-<arch>.cc. | 2293 // Used from ic-<arch>.cc. |
| 2293 RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) { | 2294 RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) { |
| 2294 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2295 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2295 HandleScope scope(isolate); | 2296 HandleScope scope(isolate); |
| 2296 DCHECK_EQ(2, args.length()); | 2297 DCHECK_EQ(2, args.length()); |
| 2298 // Runtime functions don't follow the IC's calling convention. |
| 2297 Handle<JSGlobalObject> global = isolate->global_object(); | 2299 Handle<JSGlobalObject> global = isolate->global_object(); |
| 2298 Handle<Smi> slot = args.at<Smi>(0); | 2300 Handle<Smi> slot = args.at<Smi>(0); |
| 2299 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1); | 2301 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1); |
| 2300 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2302 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2301 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, | 2303 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, |
| 2302 vector->GetKind(vector_slot)); | 2304 vector->GetKind(vector_slot)); |
| 2303 Handle<String> name(vector->GetName(vector_slot), isolate); | 2305 Handle<String> name(vector->GetName(vector_slot), isolate); |
| 2304 DCHECK_NE(*name, *isolate->factory()->empty_string()); | 2306 DCHECK_NE(*name, *isolate->factory()->empty_string()); |
| 2305 | 2307 |
| 2306 LoadGlobalICNexus nexus(vector, vector_slot); | 2308 LoadGlobalICNexus nexus(vector, vector_slot); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2357 isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); | 2359 isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); |
| 2358 } | 2360 } |
| 2359 } | 2361 } |
| 2360 return *result; | 2362 return *result; |
| 2361 } | 2363 } |
| 2362 | 2364 |
| 2363 // Used from ic-<arch>.cc | 2365 // Used from ic-<arch>.cc |
| 2364 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { | 2366 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { |
| 2365 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2367 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2366 HandleScope scope(isolate); | 2368 HandleScope scope(isolate); |
| 2369 DCHECK_EQ(4, args.length()); |
| 2370 // Runtime functions don't follow the IC's calling convention. |
| 2367 Handle<Object> receiver = args.at<Object>(0); | 2371 Handle<Object> receiver = args.at<Object>(0); |
| 2368 Handle<Object> key = args.at<Object>(1); | 2372 Handle<Object> key = args.at<Object>(1); |
| 2369 | |
| 2370 DCHECK(args.length() == 4); | |
| 2371 Handle<Smi> slot = args.at<Smi>(2); | 2373 Handle<Smi> slot = args.at<Smi>(2); |
| 2372 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); | 2374 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); |
| 2373 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2375 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2374 KeyedLoadICNexus nexus(vector, vector_slot); | 2376 KeyedLoadICNexus nexus(vector, vector_slot); |
| 2375 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2377 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2376 ic.UpdateState(receiver, key); | 2378 ic.UpdateState(receiver, key); |
| 2377 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2379 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
| 2378 } | 2380 } |
| 2379 | 2381 |
| 2380 | 2382 |
| 2381 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_MissFromStubFailure) { | 2383 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_MissFromStubFailure) { |
| 2382 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2384 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2383 HandleScope scope(isolate); | 2385 HandleScope scope(isolate); |
| 2384 DCHECK_EQ(4, args.length()); | |
| 2385 typedef LoadWithVectorDescriptor Descriptor; | 2386 typedef LoadWithVectorDescriptor Descriptor; |
| 2387 DCHECK_EQ(Descriptor::kParameterCount, args.length()); |
| 2386 Handle<Object> receiver = args.at<Object>(Descriptor::kReceiver); | 2388 Handle<Object> receiver = args.at<Object>(Descriptor::kReceiver); |
| 2387 Handle<Object> key = args.at<Object>(Descriptor::kName); | 2389 Handle<Object> key = args.at<Object>(Descriptor::kName); |
| 2388 Handle<Smi> slot = args.at<Smi>(Descriptor::kSlot); | 2390 Handle<Smi> slot = args.at<Smi>(Descriptor::kSlot); |
| 2389 Handle<TypeFeedbackVector> vector = | 2391 Handle<TypeFeedbackVector> vector = |
| 2390 args.at<TypeFeedbackVector>(Descriptor::kVector); | 2392 args.at<TypeFeedbackVector>(Descriptor::kVector); |
| 2391 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2393 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2392 KeyedLoadICNexus nexus(vector, vector_slot); | 2394 KeyedLoadICNexus nexus(vector, vector_slot); |
| 2393 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2395 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2394 ic.UpdateState(receiver, key); | 2396 ic.UpdateState(receiver, key); |
| 2395 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2397 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
| 2396 } | 2398 } |
| 2397 | 2399 |
| 2398 | 2400 |
| 2399 // Used from ic-<arch>.cc. | 2401 // Used from ic-<arch>.cc. |
| 2400 RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { | 2402 RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { |
| 2401 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2403 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2402 HandleScope scope(isolate); | 2404 HandleScope scope(isolate); |
| 2405 DCHECK_EQ(5, args.length()); |
| 2406 // Runtime functions don't follow the IC's calling convention. |
| 2403 Handle<Object> receiver = args.at<Object>(0); | 2407 Handle<Object> receiver = args.at<Object>(0); |
| 2404 Handle<Name> key = args.at<Name>(1); | 2408 Handle<Name> key = args.at<Name>(1); |
| 2405 Handle<Object> value = args.at<Object>(2); | 2409 Handle<Object> value = args.at<Object>(2); |
| 2406 | |
| 2407 DCHECK(args.length() == 5 || args.length() == 6); | |
| 2408 Handle<Smi> slot = args.at<Smi>(3); | 2410 Handle<Smi> slot = args.at<Smi>(3); |
| 2409 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); | 2411 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); |
| 2410 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2412 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2411 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { | 2413 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { |
| 2412 StoreICNexus nexus(vector, vector_slot); | 2414 StoreICNexus nexus(vector, vector_slot); |
| 2413 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2415 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2414 ic.UpdateState(receiver, key); | 2416 ic.UpdateState(receiver, key); |
| 2415 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2417 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2416 } else { | 2418 } else { |
| 2417 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, | 2419 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, |
| 2418 vector->GetKind(vector_slot)); | 2420 vector->GetKind(vector_slot)); |
| 2419 KeyedStoreICNexus nexus(vector, vector_slot); | 2421 KeyedStoreICNexus nexus(vector, vector_slot); |
| 2420 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2422 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2421 ic.UpdateState(receiver, key); | 2423 ic.UpdateState(receiver, key); |
| 2422 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2424 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2423 } | 2425 } |
| 2424 } | 2426 } |
| 2425 | 2427 |
| 2426 | 2428 |
| 2427 RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) { | 2429 RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) { |
| 2428 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2430 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2429 HandleScope scope(isolate); | 2431 HandleScope scope(isolate); |
| 2430 DCHECK_EQ(5, args.length()); | |
| 2431 typedef StoreWithVectorDescriptor Descriptor; | 2432 typedef StoreWithVectorDescriptor Descriptor; |
| 2433 DCHECK_EQ(Descriptor::kParameterCount, args.length()); |
| 2432 Handle<Object> receiver = args.at<Object>(Descriptor::kReceiver); | 2434 Handle<Object> receiver = args.at<Object>(Descriptor::kReceiver); |
| 2433 Handle<Name> key = args.at<Name>(Descriptor::kName); | 2435 Handle<Name> key = args.at<Name>(Descriptor::kName); |
| 2434 Handle<Object> value = args.at<Object>(Descriptor::kValue); | 2436 Handle<Object> value = args.at<Object>(Descriptor::kValue); |
| 2435 Handle<Smi> slot = args.at<Smi>(Descriptor::kSlot); | 2437 Handle<Smi> slot = args.at<Smi>(Descriptor::kSlot); |
| 2436 Handle<TypeFeedbackVector> vector = | 2438 Handle<TypeFeedbackVector> vector = |
| 2437 args.at<TypeFeedbackVector>(Descriptor::kVector); | 2439 args.at<TypeFeedbackVector>(Descriptor::kVector); |
| 2438 | 2440 |
| 2439 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2441 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2440 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { | 2442 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { |
| 2441 StoreICNexus nexus(vector, vector_slot); | 2443 StoreICNexus nexus(vector, vector_slot); |
| 2442 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2444 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2443 ic.UpdateState(receiver, key); | 2445 ic.UpdateState(receiver, key); |
| 2444 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2446 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2445 } else { | 2447 } else { |
| 2446 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, | 2448 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, |
| 2447 vector->GetKind(vector_slot)); | 2449 vector->GetKind(vector_slot)); |
| 2448 KeyedStoreICNexus nexus(vector, vector_slot); | 2450 KeyedStoreICNexus nexus(vector, vector_slot); |
| 2449 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2451 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2450 ic.UpdateState(receiver, key); | 2452 ic.UpdateState(receiver, key); |
| 2451 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2453 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2452 } | 2454 } |
| 2453 } | 2455 } |
| 2454 | 2456 |
| 2455 RUNTIME_FUNCTION(Runtime_TransitionStoreIC_MissFromStubFailure) { | |
| 2456 TimerEventScope<TimerEventIcMiss> timer(isolate); | |
| 2457 HandleScope scope(isolate); | |
| 2458 Handle<Object> receiver = args.at<Object>(0); | |
| 2459 Handle<Name> key = args.at<Name>(1); | |
| 2460 Handle<Object> value = args.at<Object>(2); | |
| 2461 | |
| 2462 int length = args.length(); | |
| 2463 DCHECK(length == 5 || length == 6); | |
| 2464 // TODO(ishell): use VectorStoreTransitionDescriptor indices here and update | |
| 2465 // this comment: | |
| 2466 // | |
| 2467 // We might have slot and vector, for a normal miss (slot(3), vector(4)). | |
| 2468 // Or, map and vector for a transitioning store miss (map(3), vector(4)). | |
| 2469 // In this case, we need to recover the slot from a virtual register. | |
| 2470 // If length == 6, then a map is included (map(3), slot(4), vector(5)). | |
| 2471 Handle<Smi> slot; | |
| 2472 Handle<TypeFeedbackVector> vector; | |
| 2473 if (length == 5) { | |
| 2474 vector = args.at<TypeFeedbackVector>(4); | |
| 2475 slot = handle( | |
| 2476 *reinterpret_cast<Smi**>(isolate->virtual_slot_register_address()), | |
| 2477 isolate); | |
| 2478 } else { | |
| 2479 vector = args.at<TypeFeedbackVector>(5); | |
| 2480 slot = args.at<Smi>(4); | |
| 2481 } | |
| 2482 | |
| 2483 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | |
| 2484 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { | |
| 2485 StoreICNexus nexus(vector, vector_slot); | |
| 2486 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | |
| 2487 ic.UpdateState(receiver, key); | |
| 2488 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | |
| 2489 } else { | |
| 2490 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, | |
| 2491 vector->GetKind(vector_slot)); | |
| 2492 KeyedStoreICNexus nexus(vector, vector_slot); | |
| 2493 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | |
| 2494 ic.UpdateState(receiver, key); | |
| 2495 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | |
| 2496 } | |
| 2497 } | |
| 2498 | |
| 2499 // Used from ic-<arch>.cc. | 2457 // Used from ic-<arch>.cc. |
| 2500 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) { | 2458 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) { |
| 2501 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2459 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2502 HandleScope scope(isolate); | 2460 HandleScope scope(isolate); |
| 2503 DCHECK_EQ(5, args.length()); | 2461 DCHECK_EQ(5, args.length()); |
| 2462 // Runtime functions don't follow the IC's calling convention. |
| 2504 Handle<Object> receiver = args.at<Object>(0); | 2463 Handle<Object> receiver = args.at<Object>(0); |
| 2505 Handle<Object> key = args.at<Object>(1); | 2464 Handle<Object> key = args.at<Object>(1); |
| 2506 Handle<Object> value = args.at<Object>(2); | 2465 Handle<Object> value = args.at<Object>(2); |
| 2507 Handle<Smi> slot = args.at<Smi>(3); | 2466 Handle<Smi> slot = args.at<Smi>(3); |
| 2508 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); | 2467 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); |
| 2509 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2468 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2510 KeyedStoreICNexus nexus(vector, vector_slot); | 2469 KeyedStoreICNexus nexus(vector, vector_slot); |
| 2511 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2470 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2512 ic.UpdateState(receiver, key); | 2471 ic.UpdateState(receiver, key); |
| 2513 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2472 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2514 } | 2473 } |
| 2515 | 2474 |
| 2516 | 2475 |
| 2517 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) { | 2476 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) { |
| 2518 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2477 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2519 HandleScope scope(isolate); | 2478 HandleScope scope(isolate); |
| 2520 DCHECK_EQ(5, args.length()); | |
| 2521 typedef StoreWithVectorDescriptor Descriptor; | 2479 typedef StoreWithVectorDescriptor Descriptor; |
| 2480 DCHECK_EQ(Descriptor::kParameterCount, args.length()); |
| 2522 Handle<Object> receiver = args.at<Object>(Descriptor::kReceiver); | 2481 Handle<Object> receiver = args.at<Object>(Descriptor::kReceiver); |
| 2523 Handle<Object> key = args.at<Object>(Descriptor::kName); | 2482 Handle<Object> key = args.at<Object>(Descriptor::kName); |
| 2524 Handle<Object> value = args.at<Object>(Descriptor::kValue); | 2483 Handle<Object> value = args.at<Object>(Descriptor::kValue); |
| 2525 Handle<Smi> slot = args.at<Smi>(Descriptor::kSlot); | 2484 Handle<Smi> slot = args.at<Smi>(Descriptor::kSlot); |
| 2526 Handle<TypeFeedbackVector> vector = | 2485 Handle<TypeFeedbackVector> vector = |
| 2527 args.at<TypeFeedbackVector>(Descriptor::kVector); | 2486 args.at<TypeFeedbackVector>(Descriptor::kVector); |
| 2528 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2487 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2529 KeyedStoreICNexus nexus(vector, vector_slot); | 2488 KeyedStoreICNexus nexus(vector, vector_slot); |
| 2530 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2489 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2531 ic.UpdateState(receiver, key); | 2490 ic.UpdateState(receiver, key); |
| 2532 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); | 2491 RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); |
| 2533 } | 2492 } |
| 2534 | 2493 |
| 2535 | 2494 |
| 2536 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { | 2495 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { |
| 2537 HandleScope scope(isolate); | 2496 HandleScope scope(isolate); |
| 2538 DCHECK_EQ(5, args.length()); | 2497 DCHECK_EQ(5, args.length()); |
| 2498 // Runtime functions don't follow the IC's calling convention. |
| 2539 Handle<Object> object = args.at<Object>(0); | 2499 Handle<Object> object = args.at<Object>(0); |
| 2540 Handle<Object> key = args.at<Object>(1); | 2500 Handle<Object> key = args.at<Object>(1); |
| 2541 Handle<Object> value = args.at<Object>(2); | 2501 Handle<Object> value = args.at<Object>(2); |
| 2542 LanguageMode language_mode; | 2502 LanguageMode language_mode; |
| 2543 KeyedStoreICNexus nexus(isolate); | 2503 KeyedStoreICNexus nexus(isolate); |
| 2544 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2504 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2545 language_mode = ic.language_mode(); | 2505 language_mode = ic.language_mode(); |
| 2546 RETURN_RESULT_OR_FAILURE( | 2506 RETURN_RESULT_OR_FAILURE( |
| 2547 isolate, | 2507 isolate, |
| 2548 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2508 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
| 2549 } | 2509 } |
| 2550 | 2510 |
| 2551 | 2511 |
| 2552 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { | 2512 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { |
| 2553 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2513 TimerEventScope<TimerEventIcMiss> timer(isolate); |
| 2554 HandleScope scope(isolate); | 2514 HandleScope scope(isolate); |
| 2555 // Length == 5 or 6, depending on whether the vector slot | 2515 // Runtime functions don't follow the IC's calling convention. |
| 2556 // is passed in a virtual register or not. | |
| 2557 DCHECK(args.length() == 5 || args.length() == 6); | |
| 2558 Handle<Object> object = args.at<Object>(0); | 2516 Handle<Object> object = args.at<Object>(0); |
| 2559 Handle<Object> key = args.at<Object>(1); | 2517 Handle<Object> key = args.at<Object>(1); |
| 2560 Handle<Object> value = args.at<Object>(2); | 2518 Handle<Object> value = args.at<Object>(2); |
| 2561 Handle<Map> map = args.at<Map>(3); | 2519 Handle<Map> map = args.at<Map>(3); |
| 2562 LanguageMode language_mode; | 2520 LanguageMode language_mode; |
| 2563 KeyedStoreICNexus nexus(isolate); | 2521 KeyedStoreICNexus nexus(isolate); |
| 2564 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2522 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2565 language_mode = ic.language_mode(); | 2523 language_mode = ic.language_mode(); |
| 2566 if (object->IsJSObject()) { | 2524 if (object->IsJSObject()) { |
| 2567 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), | 2525 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), |
| 2568 map->elements_kind()); | 2526 map->elements_kind()); |
| 2569 } | 2527 } |
| 2570 RETURN_RESULT_OR_FAILURE( | 2528 RETURN_RESULT_OR_FAILURE( |
| 2571 isolate, | 2529 isolate, |
| 2572 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2530 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
| 2573 } | 2531 } |
| 2574 | 2532 |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3025 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, | 2983 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, |
| 3026 vector->GetKind(vector_slot)); | 2984 vector->GetKind(vector_slot)); |
| 3027 KeyedLoadICNexus nexus(vector, vector_slot); | 2985 KeyedLoadICNexus nexus(vector, vector_slot); |
| 3028 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2986 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 3029 ic.UpdateState(receiver, key); | 2987 ic.UpdateState(receiver, key); |
| 3030 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); | 2988 RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key)); |
| 3031 } | 2989 } |
| 3032 } | 2990 } |
| 3033 } // namespace internal | 2991 } // namespace internal |
| 3034 } // namespace v8 | 2992 } // namespace v8 |
| OLD | NEW |