OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/v8.h" | 5 #include "src/v8.h" |
6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
7 | 7 |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/execution.h" | 10 #include "src/execution.h" |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 Isolate* isolate = CcTest::i_isolate(); | 201 Isolate* isolate = CcTest::i_isolate(); |
202 Heap* heap = isolate->heap(); | 202 Heap* heap = isolate->heap(); |
203 | 203 |
204 // Make sure function f has a call that uses a type feedback slot. | 204 // Make sure function f has a call that uses a type feedback slot. |
205 CompileRun( | 205 CompileRun( |
206 "function foo() { return 17; }" | 206 "function foo() { return 17; }" |
207 "function f(a) { a(); } f(foo);"); | 207 "function f(a) { a(); } f(foo);"); |
208 Handle<JSFunction> f = GetFunction("f"); | 208 Handle<JSFunction> f = GetFunction("f"); |
209 // There should be one IC. | 209 // There should be one IC. |
210 Handle<TypeFeedbackVector> feedback_vector = | 210 Handle<TypeFeedbackVector> feedback_vector = |
211 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 211 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
212 FeedbackVectorSlot slot(0); | 212 FeedbackVectorSlot slot(0); |
213 CallICNexus nexus(feedback_vector, slot); | 213 CallICNexus nexus(feedback_vector, slot); |
214 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 214 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
215 // CallIC doesn't return map feedback. | 215 // CallIC doesn't return map feedback. |
216 CHECK(!nexus.FindFirstMap()); | 216 CHECK(!nexus.FindFirstMap()); |
217 | 217 |
218 CompileRun("f(function() { return 16; })"); | 218 CompileRun("f(function() { return 16; })"); |
219 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); | 219 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); |
220 | 220 |
221 // After a collection, state should remain GENERIC. | 221 // After a collection, state should remain GENERIC. |
(...skipping 20 matching lines...) Expand all Loading... |
242 Isolate* isolate = CcTest::i_isolate(); | 242 Isolate* isolate = CcTest::i_isolate(); |
243 Heap* heap = isolate->heap(); | 243 Heap* heap = isolate->heap(); |
244 | 244 |
245 // Make sure function f has a call that uses a type feedback slot. | 245 // Make sure function f has a call that uses a type feedback slot. |
246 CompileRun( | 246 CompileRun( |
247 "var o = { foo: 3 };" | 247 "var o = { foo: 3 };" |
248 "function f(a) { return a.foo; } f(o);"); | 248 "function f(a) { return a.foo; } f(o);"); |
249 Handle<JSFunction> f = GetFunction("f"); | 249 Handle<JSFunction> f = GetFunction("f"); |
250 // There should be one IC. | 250 // There should be one IC. |
251 Handle<TypeFeedbackVector> feedback_vector = | 251 Handle<TypeFeedbackVector> feedback_vector = |
252 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 252 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
253 FeedbackVectorSlot slot(0); | 253 FeedbackVectorSlot slot(0); |
254 LoadICNexus nexus(feedback_vector, slot); | 254 LoadICNexus nexus(feedback_vector, slot); |
255 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); | 255 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); |
256 | 256 |
257 CompileRun("f(o)"); | 257 CompileRun("f(o)"); |
258 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 258 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
259 // Verify that the monomorphic map is the one we expect. | 259 // Verify that the monomorphic map is the one we expect. |
260 v8::MaybeLocal<v8::Value> v8_o = | 260 v8::MaybeLocal<v8::Value> v8_o = |
261 CcTest::global()->Get(context.local(), v8_str("o")); | 261 CcTest::global()->Get(context.local(), v8_str("o")); |
262 Handle<JSObject> o = | 262 Handle<JSObject> o = |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 CompileRun( | 301 CompileRun( |
302 "o = 10;" | 302 "o = 10;" |
303 "function f() {" | 303 "function f() {" |
304 " var x = o + 10;" | 304 " var x = o + 10;" |
305 " return o + x + o;" | 305 " return o + x + o;" |
306 "}" | 306 "}" |
307 "f();"); | 307 "f();"); |
308 Handle<JSFunction> f = GetFunction("f"); | 308 Handle<JSFunction> f = GetFunction("f"); |
309 // There should be one IC slot. | 309 // There should be one IC slot. |
310 Handle<TypeFeedbackVector> feedback_vector = | 310 Handle<TypeFeedbackVector> feedback_vector = |
311 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 311 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
312 FeedbackVectorHelper helper(feedback_vector); | 312 FeedbackVectorHelper helper(feedback_vector); |
313 CHECK_EQ(1, helper.slot_count()); | 313 CHECK_EQ(1, helper.slot_count()); |
314 FeedbackVectorSlot slot(0); | 314 FeedbackVectorSlot slot(0); |
315 LoadICNexus nexus(feedback_vector, slot); | 315 LoadICNexus nexus(feedback_vector, slot); |
316 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 316 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
317 } | 317 } |
318 | 318 |
319 | 319 |
320 TEST(VectorLoadICOnSmi) { | 320 TEST(VectorLoadICOnSmi) { |
321 if (i::FLAG_always_opt) return; | 321 if (i::FLAG_always_opt) return; |
322 CcTest::InitializeVM(); | 322 CcTest::InitializeVM(); |
323 LocalContext context; | 323 LocalContext context; |
324 v8::HandleScope scope(context->GetIsolate()); | 324 v8::HandleScope scope(context->GetIsolate()); |
325 Isolate* isolate = CcTest::i_isolate(); | 325 Isolate* isolate = CcTest::i_isolate(); |
326 Heap* heap = isolate->heap(); | 326 Heap* heap = isolate->heap(); |
327 | 327 |
328 // Make sure function f has a call that uses a type feedback slot. | 328 // Make sure function f has a call that uses a type feedback slot. |
329 CompileRun( | 329 CompileRun( |
330 "var o = { foo: 3 };" | 330 "var o = { foo: 3 };" |
331 "function f(a) { return a.foo; } f(o);"); | 331 "function f(a) { return a.foo; } f(o);"); |
332 Handle<JSFunction> f = GetFunction("f"); | 332 Handle<JSFunction> f = GetFunction("f"); |
333 // There should be one IC. | 333 // There should be one IC. |
334 Handle<TypeFeedbackVector> feedback_vector = | 334 Handle<TypeFeedbackVector> feedback_vector = |
335 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 335 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
336 FeedbackVectorSlot slot(0); | 336 FeedbackVectorSlot slot(0); |
337 LoadICNexus nexus(feedback_vector, slot); | 337 LoadICNexus nexus(feedback_vector, slot); |
338 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); | 338 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); |
339 | 339 |
340 CompileRun("f(34)"); | 340 CompileRun("f(34)"); |
341 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 341 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
342 // Verify that the monomorphic map is the one we expect. | 342 // Verify that the monomorphic map is the one we expect. |
343 Map* number_map = heap->heap_number_map(); | 343 Map* number_map = heap->heap_number_map(); |
344 CHECK_EQ(number_map, nexus.FindFirstMap()); | 344 CHECK_EQ(number_map, nexus.FindFirstMap()); |
345 | 345 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 " y = a;" | 390 " y = a;" |
391 " return y;" | 391 " return y;" |
392 "}" | 392 "}" |
393 "a = 3;" | 393 "a = 3;" |
394 "testvar({});"); | 394 "testvar({});"); |
395 | 395 |
396 Handle<JSFunction> f = GetFunction("testvar"); | 396 Handle<JSFunction> f = GetFunction("testvar"); |
397 | 397 |
398 // There should be two LOAD_ICs, one for a and one for y at the end. | 398 // There should be two LOAD_ICs, one for a and one for y at the end. |
399 Handle<TypeFeedbackVector> feedback_vector = | 399 Handle<TypeFeedbackVector> feedback_vector = |
400 handle(f->shared()->feedback_vector(), isolate); | 400 handle(f->feedback_vector(), isolate); |
401 FeedbackVectorHelper helper(feedback_vector); | 401 FeedbackVectorHelper helper(feedback_vector); |
402 CHECK_EQ(4, helper.slot_count()); | 402 CHECK_EQ(4, helper.slot_count()); |
403 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_IC); | 403 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_IC); |
404 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); | 404 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); |
405 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); | 405 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); |
406 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); | 406 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); |
407 } | 407 } |
408 | 408 |
409 { | 409 { |
410 CompileRun( | 410 CompileRun( |
411 "function testprop(x) {" | 411 "function testprop(x) {" |
412 " x.blue = a;" | 412 " x.blue = a;" |
413 "}" | 413 "}" |
414 "testprop({ blue: 3 });"); | 414 "testprop({ blue: 3 });"); |
415 | 415 |
416 Handle<JSFunction> f = GetFunction("testprop"); | 416 Handle<JSFunction> f = GetFunction("testprop"); |
417 | 417 |
418 // There should be one LOAD_IC, for the load of a. | 418 // There should be one LOAD_IC, for the load of a. |
419 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 419 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
420 FeedbackVectorHelper helper(feedback_vector); | 420 FeedbackVectorHelper helper(feedback_vector); |
421 CHECK_EQ(2, helper.slot_count()); | 421 CHECK_EQ(2, helper.slot_count()); |
422 } | 422 } |
423 | 423 |
424 { | 424 { |
425 CompileRun( | 425 CompileRun( |
426 "function testpropfunc(x) {" | 426 "function testpropfunc(x) {" |
427 " x().blue = a;" | 427 " x().blue = a;" |
428 " return x().blue;" | 428 " return x().blue;" |
429 "}" | 429 "}" |
430 "function makeresult() { return { blue: 3 }; }" | 430 "function makeresult() { return { blue: 3 }; }" |
431 "testpropfunc(makeresult);"); | 431 "testpropfunc(makeresult);"); |
432 | 432 |
433 Handle<JSFunction> f = GetFunction("testpropfunc"); | 433 Handle<JSFunction> f = GetFunction("testpropfunc"); |
434 | 434 |
435 // There should be 2 LOAD_ICs and 2 CALL_ICs. | 435 // There should be 2 LOAD_ICs and 2 CALL_ICs. |
436 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 436 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
437 FeedbackVectorHelper helper(feedback_vector); | 437 FeedbackVectorHelper helper(feedback_vector); |
438 CHECK_EQ(5, helper.slot_count()); | 438 CHECK_EQ(5, helper.slot_count()); |
439 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); | 439 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); |
440 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); | 440 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); |
441 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); | 441 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); |
442 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); | 442 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); |
443 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); | 443 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); |
444 } | 444 } |
445 | 445 |
446 { | 446 { |
447 CompileRun( | 447 CompileRun( |
448 "function testkeyedprop(x) {" | 448 "function testkeyedprop(x) {" |
449 " x[0] = a;" | 449 " x[0] = a;" |
450 " return x[0];" | 450 " return x[0];" |
451 "}" | 451 "}" |
452 "testkeyedprop([0, 1, 2]);"); | 452 "testkeyedprop([0, 1, 2]);"); |
453 | 453 |
454 Handle<JSFunction> f = GetFunction("testkeyedprop"); | 454 Handle<JSFunction> f = GetFunction("testkeyedprop"); |
455 | 455 |
456 // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for | 456 // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for |
457 // the load of x[0] in the return statement. | 457 // the load of x[0] in the return statement. |
458 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 458 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
459 FeedbackVectorHelper helper(feedback_vector); | 459 FeedbackVectorHelper helper(feedback_vector); |
460 CHECK_EQ(3, helper.slot_count()); | 460 CHECK_EQ(3, helper.slot_count()); |
461 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); | 461 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); |
462 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); | 462 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); |
463 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); | 463 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); |
464 } | 464 } |
465 | 465 |
466 { | 466 { |
467 CompileRun( | 467 CompileRun( |
468 "function testcompound(x) {" | 468 "function testcompound(x) {" |
469 " x.old = x.young = x.in_between = a;" | 469 " x.old = x.young = x.in_between = a;" |
470 " return x.old + x.young;" | 470 " return x.old + x.young;" |
471 "}" | 471 "}" |
472 "testcompound({ old: 3, young: 3, in_between: 3 });"); | 472 "testcompound({ old: 3, young: 3, in_between: 3 });"); |
473 | 473 |
474 Handle<JSFunction> f = GetFunction("testcompound"); | 474 Handle<JSFunction> f = GetFunction("testcompound"); |
475 | 475 |
476 // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. | 476 // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. |
477 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 477 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
478 FeedbackVectorHelper helper(feedback_vector); | 478 FeedbackVectorHelper helper(feedback_vector); |
479 CHECK_EQ(6, helper.slot_count()); | 479 CHECK_EQ(6, helper.slot_count()); |
480 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); | 480 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); |
481 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_IC); | 481 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_IC); |
482 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); | 482 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); |
483 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_IC); | 483 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_IC); |
484 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); | 484 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); |
485 CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); | 485 CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); |
486 } | 486 } |
487 } | 487 } |
488 | 488 |
489 | 489 |
490 TEST(VectorStoreICBasic) { | 490 TEST(VectorStoreICBasic) { |
491 if (i::FLAG_always_opt) return; | 491 if (i::FLAG_always_opt) return; |
492 | 492 |
493 CcTest::InitializeVM(); | 493 CcTest::InitializeVM(); |
494 LocalContext context; | 494 LocalContext context; |
495 v8::HandleScope scope(context->GetIsolate()); | 495 v8::HandleScope scope(context->GetIsolate()); |
496 | 496 |
497 CompileRun( | 497 CompileRun( |
498 "function f(a) {" | 498 "function f(a) {" |
499 " a.foo = 5;" | 499 " a.foo = 5;" |
500 "}" | 500 "}" |
501 "var a = { foo: 3 };" | 501 "var a = { foo: 3 };" |
502 "f(a);" | 502 "f(a);" |
503 "f(a);" | 503 "f(a);" |
504 "f(a);"); | 504 "f(a);"); |
505 Handle<JSFunction> f = GetFunction("f"); | 505 Handle<JSFunction> f = GetFunction("f"); |
506 // There should be one IC slot. | 506 // There should be one IC slot. |
507 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 507 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
508 FeedbackVectorHelper helper(feedback_vector); | 508 FeedbackVectorHelper helper(feedback_vector); |
509 CHECK_EQ(1, helper.slot_count()); | 509 CHECK_EQ(1, helper.slot_count()); |
510 FeedbackVectorSlot slot(0); | 510 FeedbackVectorSlot slot(0); |
511 StoreICNexus nexus(feedback_vector, slot); | 511 StoreICNexus nexus(feedback_vector, slot); |
512 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 512 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
513 } | 513 } |
514 | 514 |
515 } // namespace | 515 } // namespace |
OLD | NEW |