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 |