OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/v8.h" |
| 6 #include "test/cctest/cctest.h" |
| 7 |
| 8 #include "src/api.h" |
| 9 #include "src/debug.h" |
| 10 #include "src/execution.h" |
| 11 #include "src/factory.h" |
| 12 #include "src/global-handles.h" |
| 13 #include "src/macro-assembler.h" |
| 14 #include "src/objects.h" |
| 15 |
| 16 using namespace v8::internal; |
| 17 |
| 18 namespace { |
| 19 |
| 20 TEST(VectorStructure) { |
| 21 LocalContext context; |
| 22 v8::HandleScope scope(context->GetIsolate()); |
| 23 Isolate* isolate = CcTest::i_isolate(); |
| 24 Factory* factory = isolate->factory(); |
| 25 |
| 26 // Empty vectors are the empty fixed array. |
| 27 Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(0, 0); |
| 28 CHECK(Handle<FixedArray>::cast(vector) |
| 29 .is_identical_to(factory->empty_fixed_array())); |
| 30 // Which can nonetheless be queried. |
| 31 CHECK_EQ(0, vector->ic_with_type_info_count()); |
| 32 CHECK_EQ(0, vector->ic_generic_count()); |
| 33 CHECK_EQ(0, vector->Slots()); |
| 34 CHECK_EQ(0, vector->ICSlots()); |
| 35 |
| 36 vector = factory->NewTypeFeedbackVector(1, 0); |
| 37 CHECK_EQ(1, vector->Slots()); |
| 38 CHECK_EQ(0, vector->ICSlots()); |
| 39 |
| 40 vector = factory->NewTypeFeedbackVector(0, 1); |
| 41 CHECK_EQ(0, vector->Slots()); |
| 42 CHECK_EQ(1, vector->ICSlots()); |
| 43 |
| 44 vector = factory->NewTypeFeedbackVector(3, 5); |
| 45 CHECK_EQ(3, vector->Slots()); |
| 46 CHECK_EQ(5, vector->ICSlots()); |
| 47 |
| 48 int index = vector->GetIndex(FeedbackVectorSlot(0)); |
| 49 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount, index); |
| 50 CHECK(FeedbackVectorSlot(0) == vector->ToSlot(index)); |
| 51 |
| 52 index = vector->GetIndex(FeedbackVectorICSlot(0)); |
| 53 CHECK_EQ(index, TypeFeedbackVector::kReservedIndexCount + 3); |
| 54 CHECK(FeedbackVectorICSlot(0) == vector->ToICSlot(index)); |
| 55 |
| 56 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + 3 + 5, vector->length()); |
| 57 } |
| 58 |
| 59 |
| 60 TEST(VectorSlotClearing) { |
| 61 LocalContext context; |
| 62 v8::HandleScope scope(context->GetIsolate()); |
| 63 Isolate* isolate = CcTest::i_isolate(); |
| 64 Factory* factory = isolate->factory(); |
| 65 |
| 66 // We only test clearing FeedbackVectorSlots, not FeedbackVectorICSlots. |
| 67 // The reason is that FeedbackVectorICSlots need a full code environment |
| 68 // to fully test (See VectorICProfilerStatistics test below). |
| 69 Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(5, 0); |
| 70 |
| 71 // Fill with information |
| 72 vector->Set(FeedbackVectorSlot(0), Smi::FromInt(1)); |
| 73 vector->Set(FeedbackVectorSlot(1), *factory->fixed_array_map()); |
| 74 vector->Set(FeedbackVectorSlot(2), *factory->NewAllocationSite()); |
| 75 |
| 76 vector->ClearSlots(NULL); |
| 77 |
| 78 // The feedback vector slots are cleared. AllocationSites are granted |
| 79 // an exemption from clearing, as are smis. |
| 80 CHECK_EQ(Smi::FromInt(1), vector->Get(FeedbackVectorSlot(0))); |
| 81 CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate), |
| 82 vector->Get(FeedbackVectorSlot(1))); |
| 83 CHECK(vector->Get(FeedbackVectorSlot(2))->IsAllocationSite()); |
| 84 } |
| 85 |
| 86 |
| 87 TEST(VectorICProfilerStatistics) { |
| 88 if (i::FLAG_always_opt) return; |
| 89 CcTest::InitializeVM(); |
| 90 LocalContext context; |
| 91 v8::HandleScope scope(context->GetIsolate()); |
| 92 Isolate* isolate = CcTest::i_isolate(); |
| 93 Heap* heap = isolate->heap(); |
| 94 |
| 95 // Make sure function f has a call that uses a type feedback slot. |
| 96 CompileRun( |
| 97 "function fun() {};" |
| 98 "function f(a) { a(); } f(fun);"); |
| 99 Handle<JSFunction> f = v8::Utils::OpenHandle( |
| 100 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); |
| 101 // There should be one IC. |
| 102 Code* code = f->shared()->code(); |
| 103 TypeFeedbackInfo* feedback_info = |
| 104 TypeFeedbackInfo::cast(code->type_feedback_info()); |
| 105 CHECK_EQ(1, feedback_info->ic_total_count()); |
| 106 CHECK_EQ(0, feedback_info->ic_with_type_info_count()); |
| 107 CHECK_EQ(0, feedback_info->ic_generic_count()); |
| 108 TypeFeedbackVector* feedback_vector = f->shared()->feedback_vector(); |
| 109 CHECK_EQ(1, feedback_vector->ic_with_type_info_count()); |
| 110 CHECK_EQ(0, feedback_vector->ic_generic_count()); |
| 111 |
| 112 // Now send the information generic. |
| 113 CompileRun("f(Object);"); |
| 114 feedback_vector = f->shared()->feedback_vector(); |
| 115 CHECK_EQ(0, feedback_vector->ic_with_type_info_count()); |
| 116 CHECK_EQ(1, feedback_vector->ic_generic_count()); |
| 117 |
| 118 // A collection will make the site uninitialized again. |
| 119 heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 120 feedback_vector = f->shared()->feedback_vector(); |
| 121 CHECK_EQ(0, feedback_vector->ic_with_type_info_count()); |
| 122 CHECK_EQ(0, feedback_vector->ic_generic_count()); |
| 123 |
| 124 // The Array function is special. A call to array remains monomorphic |
| 125 // and isn't cleared by gc because an AllocationSite is being held. |
| 126 CompileRun("f(Array);"); |
| 127 feedback_vector = f->shared()->feedback_vector(); |
| 128 CHECK_EQ(1, feedback_vector->ic_with_type_info_count()); |
| 129 CHECK_EQ(0, feedback_vector->ic_generic_count()); |
| 130 |
| 131 CHECK(feedback_vector->Get(FeedbackVectorICSlot(0))->IsAllocationSite()); |
| 132 heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 133 feedback_vector = f->shared()->feedback_vector(); |
| 134 CHECK_EQ(1, feedback_vector->ic_with_type_info_count()); |
| 135 CHECK_EQ(0, feedback_vector->ic_generic_count()); |
| 136 CHECK(feedback_vector->Get(FeedbackVectorICSlot(0))->IsAllocationSite()); |
| 137 } |
| 138 } |
OLD | NEW |