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" |
11 #include "src/factory.h" | 11 #include "src/factory.h" |
12 #include "src/global-handles.h" | 12 #include "src/global-handles.h" |
13 #include "src/macro-assembler.h" | 13 #include "src/macro-assembler.h" |
14 #include "src/objects.h" | 14 #include "src/objects.h" |
15 | 15 |
16 using namespace v8::internal; | 16 using namespace v8::internal; |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
| 20 #define CHECK_SLOT_KIND(vector, slot, expected_kind) \ |
| 21 CHECK_EQ(expected_kind, vector->GetKind(FeedbackVectorICSlot(slot))); |
| 22 |
| 23 |
20 TEST(VectorStructure) { | 24 TEST(VectorStructure) { |
21 LocalContext context; | 25 LocalContext context; |
22 v8::HandleScope scope(context->GetIsolate()); | 26 v8::HandleScope scope(context->GetIsolate()); |
23 Isolate* isolate = CcTest::i_isolate(); | 27 Isolate* isolate = CcTest::i_isolate(); |
24 Factory* factory = isolate->factory(); | 28 Factory* factory = isolate->factory(); |
25 Zone* zone = isolate->runtime_zone(); | 29 Zone* zone = isolate->runtime_zone(); |
26 | 30 |
27 // Empty vectors are the empty fixed array. | 31 // Empty vectors are the empty fixed array. |
28 FeedbackVectorSpec empty; | 32 FeedbackVectorSpec empty; |
29 Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&empty); | 33 Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&empty); |
30 CHECK(Handle<FixedArray>::cast(vector) | 34 CHECK(Handle<FixedArray>::cast(vector) |
31 .is_identical_to(factory->empty_fixed_array())); | 35 .is_identical_to(factory->empty_fixed_array())); |
32 // Which can nonetheless be queried. | 36 // Which can nonetheless be queried. |
33 CHECK_EQ(0, vector->ic_with_type_info_count()); | 37 CHECK_EQ(0, vector->ic_with_type_info_count()); |
34 CHECK_EQ(0, vector->ic_generic_count()); | 38 CHECK_EQ(0, vector->ic_generic_count()); |
35 CHECK_EQ(0, vector->Slots()); | 39 CHECK_EQ(0, vector->Slots()); |
36 CHECK_EQ(0, vector->ICSlots()); | 40 CHECK_EQ(0, vector->ICSlots()); |
37 | 41 |
38 FeedbackVectorSpec one_slot(1); | 42 FeedbackVectorSpec one_slot(1); |
39 vector = factory->NewTypeFeedbackVector(&one_slot); | 43 vector = factory->NewTypeFeedbackVector(&one_slot); |
40 CHECK_EQ(1, vector->Slots()); | 44 CHECK_EQ(1, vector->Slots()); |
41 CHECK_EQ(0, vector->ICSlots()); | 45 CHECK_EQ(0, vector->ICSlots()); |
42 | 46 |
43 ZoneFeedbackVectorSpec one_icslot(zone, 0, 1); | 47 ZoneFeedbackVectorSpec one_icslot(zone, 0, 1); |
44 one_icslot.SetKind(0, Code::CALL_IC); | 48 one_icslot.SetKind(0, FeedbackVectorSlotKind::CALL_IC); |
45 vector = factory->NewTypeFeedbackVector(&one_icslot); | 49 vector = factory->NewTypeFeedbackVector(&one_icslot); |
46 CHECK_EQ(0, vector->Slots()); | 50 CHECK_EQ(0, vector->Slots()); |
47 CHECK_EQ(1, vector->ICSlots()); | 51 CHECK_EQ(1, vector->ICSlots()); |
48 | 52 |
49 ZoneFeedbackVectorSpec spec(zone, 3, 5); | 53 ZoneFeedbackVectorSpec spec(zone, 3, 5); |
50 for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC); | 54 for (int i = 0; i < 5; i++) spec.SetKind(i, FeedbackVectorSlotKind::CALL_IC); |
51 vector = factory->NewTypeFeedbackVector(&spec); | 55 vector = factory->NewTypeFeedbackVector(&spec); |
52 CHECK_EQ(3, vector->Slots()); | 56 CHECK_EQ(3, vector->Slots()); |
53 CHECK_EQ(5, vector->ICSlots()); | 57 CHECK_EQ(5, vector->ICSlots()); |
54 | 58 |
55 int metadata_length = vector->ic_metadata_length(); | 59 int metadata_length = vector->ic_metadata_length(); |
56 CHECK(metadata_length > 0); | 60 CHECK(metadata_length > 0); |
57 | 61 |
58 int index = vector->GetIndex(FeedbackVectorSlot(0)); | 62 int index = vector->GetIndex(FeedbackVectorSlot(0)); |
59 | 63 |
60 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length, index); | 64 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length, index); |
(...skipping 13 matching lines...) Expand all Loading... |
74 TEST(VectorICMetadata) { | 78 TEST(VectorICMetadata) { |
75 LocalContext context; | 79 LocalContext context; |
76 v8::HandleScope scope(context->GetIsolate()); | 80 v8::HandleScope scope(context->GetIsolate()); |
77 Isolate* isolate = CcTest::i_isolate(); | 81 Isolate* isolate = CcTest::i_isolate(); |
78 Factory* factory = isolate->factory(); | 82 Factory* factory = isolate->factory(); |
79 Zone* zone = isolate->runtime_zone(); | 83 Zone* zone = isolate->runtime_zone(); |
80 | 84 |
81 ZoneFeedbackVectorSpec spec(zone, 10, 3 * 10); | 85 ZoneFeedbackVectorSpec spec(zone, 10, 3 * 10); |
82 // Set metadata. | 86 // Set metadata. |
83 for (int i = 0; i < 30; i++) { | 87 for (int i = 0; i < 30; i++) { |
84 Code::Kind kind; | 88 FeedbackVectorSlotKind kind; |
85 if (i % 3 == 0) { | 89 if (i % 3 == 0) { |
86 kind = Code::CALL_IC; | 90 kind = FeedbackVectorSlotKind::CALL_IC; |
87 } else if (i % 3 == 1) { | 91 } else if (i % 3 == 1) { |
88 kind = Code::LOAD_IC; | 92 kind = FeedbackVectorSlotKind::LOAD_IC; |
89 } else { | 93 } else { |
90 kind = Code::KEYED_LOAD_IC; | 94 kind = FeedbackVectorSlotKind::KEYED_LOAD_IC; |
91 } | 95 } |
92 spec.SetKind(i, kind); | 96 spec.SetKind(i, kind); |
93 } | 97 } |
94 | 98 |
95 Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&spec); | 99 Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&spec); |
96 CHECK_EQ(10, vector->Slots()); | 100 CHECK_EQ(10, vector->Slots()); |
97 CHECK_EQ(3 * 10, vector->ICSlots()); | 101 CHECK_EQ(3 * 10, vector->ICSlots()); |
98 | 102 |
99 // Meanwhile set some feedback values and type feedback values to | 103 // Meanwhile set some feedback values and type feedback values to |
100 // verify the data structure remains intact. | 104 // verify the data structure remains intact. |
101 vector->change_ic_with_type_info_count(100); | 105 vector->change_ic_with_type_info_count(100); |
102 vector->change_ic_generic_count(3333); | 106 vector->change_ic_generic_count(3333); |
103 vector->Set(FeedbackVectorSlot(0), *vector); | 107 vector->Set(FeedbackVectorSlot(0), *vector); |
104 | 108 |
105 // Verify the metadata is correctly set up from the spec. | 109 // Verify the metadata is correctly set up from the spec. |
106 for (int i = 0; i < 30; i++) { | 110 for (int i = 0; i < 30; i++) { |
107 Code::Kind kind = vector->GetKind(FeedbackVectorICSlot(i)); | 111 FeedbackVectorSlotKind kind = vector->GetKind(FeedbackVectorICSlot(i)); |
108 if (i % 3 == 0) { | 112 if (i % 3 == 0) { |
109 CHECK_EQ(Code::CALL_IC, kind); | 113 CHECK_EQ(FeedbackVectorSlotKind::CALL_IC, kind); |
110 } else if (i % 3 == 1) { | 114 } else if (i % 3 == 1) { |
111 CHECK_EQ(Code::LOAD_IC, kind); | 115 CHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, kind); |
112 } else { | 116 } else { |
113 CHECK_EQ(Code::KEYED_LOAD_IC, kind); | 117 CHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, kind); |
114 } | 118 } |
115 } | 119 } |
116 } | 120 } |
117 | 121 |
118 | 122 |
119 TEST(VectorSlotClearing) { | 123 TEST(VectorSlotClearing) { |
120 LocalContext context; | 124 LocalContext context; |
121 v8::HandleScope scope(context->GetIsolate()); | 125 v8::HandleScope scope(context->GetIsolate()); |
122 Isolate* isolate = CcTest::i_isolate(); | 126 Isolate* isolate = CcTest::i_isolate(); |
123 Factory* factory = isolate->factory(); | 127 Factory* factory = isolate->factory(); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 "a = 3;" | 415 "a = 3;" |
412 "testvar({});"); | 416 "testvar({});"); |
413 | 417 |
414 Handle<JSFunction> f = GetFunction("testvar"); | 418 Handle<JSFunction> f = GetFunction("testvar"); |
415 | 419 |
416 // There should be two LOAD_ICs, one for a and one for y at the end. | 420 // There should be two LOAD_ICs, one for a and one for y at the end. |
417 Handle<TypeFeedbackVector> feedback_vector = | 421 Handle<TypeFeedbackVector> feedback_vector = |
418 handle(f->shared()->feedback_vector(), isolate); | 422 handle(f->shared()->feedback_vector(), isolate); |
419 if (FLAG_vector_stores) { | 423 if (FLAG_vector_stores) { |
420 CHECK_EQ(4, feedback_vector->ICSlots()); | 424 CHECK_EQ(4, feedback_vector->ICSlots()); |
421 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::STORE_IC); | 425 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::STORE_IC); |
422 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); | 426 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC); |
423 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::STORE_IC); | 427 CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::STORE_IC); |
424 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::LOAD_IC); | 428 CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::LOAD_IC); |
425 } else { | 429 } else { |
426 CHECK_EQ(2, feedback_vector->ICSlots()); | 430 CHECK_EQ(2, feedback_vector->ICSlots()); |
427 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); | 431 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC); |
428 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); | 432 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC); |
429 } | 433 } |
430 | 434 |
431 CompileRun( | 435 CompileRun( |
432 "function testprop(x) {" | 436 "function testprop(x) {" |
433 " x.blue = a;" | 437 " x.blue = a;" |
434 "}" | 438 "}" |
435 "testprop({ blue: 3 });"); | 439 "testprop({ blue: 3 });"); |
436 | 440 |
437 f = GetFunction("testprop"); | 441 f = GetFunction("testprop"); |
438 | 442 |
(...skipping 12 matching lines...) Expand all Loading... |
451 "}" | 455 "}" |
452 "function makeresult() { return { blue: 3 }; }" | 456 "function makeresult() { return { blue: 3 }; }" |
453 "testpropfunc(makeresult);"); | 457 "testpropfunc(makeresult);"); |
454 | 458 |
455 f = GetFunction("testpropfunc"); | 459 f = GetFunction("testpropfunc"); |
456 | 460 |
457 // There should be 2 LOAD_ICs and 2 CALL_ICs. | 461 // There should be 2 LOAD_ICs and 2 CALL_ICs. |
458 feedback_vector = handle(f->shared()->feedback_vector(), isolate); | 462 feedback_vector = handle(f->shared()->feedback_vector(), isolate); |
459 if (FLAG_vector_stores) { | 463 if (FLAG_vector_stores) { |
460 CHECK_EQ(5, feedback_vector->ICSlots()); | 464 CHECK_EQ(5, feedback_vector->ICSlots()); |
461 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::CALL_IC); | 465 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::CALL_IC); |
462 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); | 466 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC); |
463 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::STORE_IC); | 467 CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::STORE_IC); |
464 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::CALL_IC); | 468 CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::CALL_IC); |
465 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(4)) == Code::LOAD_IC); | 469 CHECK_SLOT_KIND(feedback_vector, 4, FeedbackVectorSlotKind::LOAD_IC); |
466 } else { | 470 } else { |
467 CHECK_EQ(4, feedback_vector->ICSlots()); | 471 CHECK_EQ(4, feedback_vector->ICSlots()); |
468 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::CALL_IC); | 472 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::CALL_IC); |
469 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); | 473 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC); |
470 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::CALL_IC); | 474 CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::CALL_IC); |
471 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::LOAD_IC); | 475 CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::LOAD_IC); |
472 } | 476 } |
473 | 477 |
474 CompileRun( | 478 CompileRun( |
475 "function testkeyedprop(x) {" | 479 "function testkeyedprop(x) {" |
476 " x[0] = a;" | 480 " x[0] = a;" |
477 " return x[0];" | 481 " return x[0];" |
478 "}" | 482 "}" |
479 "testkeyedprop([0, 1, 2]);"); | 483 "testkeyedprop([0, 1, 2]);"); |
480 | 484 |
481 f = GetFunction("testkeyedprop"); | 485 f = GetFunction("testkeyedprop"); |
482 | 486 |
483 // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for the | 487 // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for the |
484 // load of x[0] in the return statement. | 488 // load of x[0] in the return statement. |
485 feedback_vector = handle(f->shared()->feedback_vector(), isolate); | 489 feedback_vector = handle(f->shared()->feedback_vector(), isolate); |
486 if (FLAG_vector_stores) { | 490 if (FLAG_vector_stores) { |
487 CHECK_EQ(3, feedback_vector->ICSlots()); | 491 CHECK_EQ(3, feedback_vector->ICSlots()); |
488 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); | 492 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC); |
489 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == | 493 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); |
490 Code::KEYED_STORE_IC); | 494 CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); |
491 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == | |
492 Code::KEYED_LOAD_IC); | |
493 } else { | 495 } else { |
494 CHECK_EQ(2, feedback_vector->ICSlots()); | 496 CHECK_EQ(2, feedback_vector->ICSlots()); |
495 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); | 497 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC); |
496 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == | 498 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::KEYED_LOAD_IC); |
497 Code::KEYED_LOAD_IC); | |
498 } | 499 } |
499 | 500 |
500 CompileRun( | 501 CompileRun( |
501 "function testcompound(x) {" | 502 "function testcompound(x) {" |
502 " x.old = x.young = x.in_between = a;" | 503 " x.old = x.young = x.in_between = a;" |
503 " return x.old + x.young;" | 504 " return x.old + x.young;" |
504 "}" | 505 "}" |
505 "testcompound({ old: 3, young: 3, in_between: 3 });"); | 506 "testcompound({ old: 3, young: 3, in_between: 3 });"); |
506 | 507 |
507 f = GetFunction("testcompound"); | 508 f = GetFunction("testcompound"); |
508 | 509 |
509 // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. | 510 // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. |
510 feedback_vector = handle(f->shared()->feedback_vector(), isolate); | 511 feedback_vector = handle(f->shared()->feedback_vector(), isolate); |
511 if (FLAG_vector_stores) { | 512 if (FLAG_vector_stores) { |
512 CHECK_EQ(6, feedback_vector->ICSlots()); | 513 CHECK_EQ(6, feedback_vector->ICSlots()); |
513 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); | 514 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC); |
514 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::STORE_IC); | 515 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::STORE_IC); |
515 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::STORE_IC); | 516 CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::STORE_IC); |
516 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::STORE_IC); | 517 CHECK_SLOT_KIND(feedback_vector, 3, FeedbackVectorSlotKind::STORE_IC); |
517 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(4)) == Code::LOAD_IC); | 518 CHECK_SLOT_KIND(feedback_vector, 4, FeedbackVectorSlotKind::LOAD_IC); |
518 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(5)) == Code::LOAD_IC); | 519 CHECK_SLOT_KIND(feedback_vector, 5, FeedbackVectorSlotKind::LOAD_IC); |
519 } else { | 520 } else { |
520 CHECK_EQ(3, feedback_vector->ICSlots()); | 521 CHECK_EQ(3, feedback_vector->ICSlots()); |
521 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); | 522 CHECK_SLOT_KIND(feedback_vector, 0, FeedbackVectorSlotKind::LOAD_IC); |
522 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); | 523 CHECK_SLOT_KIND(feedback_vector, 1, FeedbackVectorSlotKind::LOAD_IC); |
523 CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::LOAD_IC); | 524 CHECK_SLOT_KIND(feedback_vector, 2, FeedbackVectorSlotKind::LOAD_IC); |
524 } | 525 } |
525 } | 526 } |
526 | 527 |
527 | 528 |
528 TEST(VectorStoreICBasic) { | 529 TEST(VectorStoreICBasic) { |
529 if (i::FLAG_always_opt) return; | 530 if (i::FLAG_always_opt) return; |
530 if (!i::FLAG_vector_stores) return; | 531 if (!i::FLAG_vector_stores) return; |
531 | 532 |
532 CcTest::InitializeVM(); | 533 CcTest::InitializeVM(); |
533 LocalContext context; | 534 LocalContext context; |
(...skipping 11 matching lines...) Expand all Loading... |
545 Handle<JSFunction> f = GetFunction("f"); | 546 Handle<JSFunction> f = GetFunction("f"); |
546 // There should be one IC slot. | 547 // There should be one IC slot. |
547 Handle<TypeFeedbackVector> feedback_vector = | 548 Handle<TypeFeedbackVector> feedback_vector = |
548 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 549 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); |
549 CHECK_EQ(1, feedback_vector->ICSlots()); | 550 CHECK_EQ(1, feedback_vector->ICSlots()); |
550 FeedbackVectorICSlot slot(0); | 551 FeedbackVectorICSlot slot(0); |
551 StoreICNexus nexus(feedback_vector, slot); | 552 StoreICNexus nexus(feedback_vector, slot); |
552 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 553 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
553 } | 554 } |
554 } | 555 } |
OLD | NEW |