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.h" | 9 #include "src/debug.h" |
10 #include "src/execution.h" | 10 #include "src/execution.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 vector = factory->NewTypeFeedbackVector(&one_slot); | 39 vector = factory->NewTypeFeedbackVector(&one_slot); |
40 CHECK_EQ(1, vector->Slots()); | 40 CHECK_EQ(1, vector->Slots()); |
41 CHECK_EQ(0, vector->ICSlots()); | 41 CHECK_EQ(0, vector->ICSlots()); |
42 | 42 |
43 FeedbackVectorSpec one_icslot(0, Code::CALL_IC); | 43 FeedbackVectorSpec one_icslot(0, Code::CALL_IC); |
44 vector = factory->NewTypeFeedbackVector(&one_icslot); | 44 vector = factory->NewTypeFeedbackVector(&one_icslot); |
45 CHECK_EQ(0, vector->Slots()); | 45 CHECK_EQ(0, vector->Slots()); |
46 CHECK_EQ(1, vector->ICSlots()); | 46 CHECK_EQ(1, vector->ICSlots()); |
47 | 47 |
48 ZoneFeedbackVectorSpec spec(zone, 3, 5); | 48 ZoneFeedbackVectorSpec spec(zone, 3, 5); |
49 if (FLAG_vector_ics) { | 49 for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC); |
50 for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC); | |
51 } | |
52 vector = factory->NewTypeFeedbackVector(&spec); | 50 vector = factory->NewTypeFeedbackVector(&spec); |
53 CHECK_EQ(3, vector->Slots()); | 51 CHECK_EQ(3, vector->Slots()); |
54 CHECK_EQ(5, vector->ICSlots()); | 52 CHECK_EQ(5, vector->ICSlots()); |
55 | 53 |
56 int metadata_length = vector->ic_metadata_length(); | 54 int metadata_length = vector->ic_metadata_length(); |
57 if (!FLAG_vector_ics) { | 55 CHECK(metadata_length > 0); |
58 CHECK_EQ(0, metadata_length); | |
59 } else { | |
60 CHECK(metadata_length > 0); | |
61 } | |
62 | 56 |
63 int index = vector->GetIndex(FeedbackVectorSlot(0)); | 57 int index = vector->GetIndex(FeedbackVectorSlot(0)); |
64 | 58 |
65 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length, index); | 59 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length, index); |
66 CHECK(FeedbackVectorSlot(0) == vector->ToSlot(index)); | 60 CHECK(FeedbackVectorSlot(0) == vector->ToSlot(index)); |
67 | 61 |
68 index = vector->GetIndex(FeedbackVectorICSlot(0)); | 62 index = vector->GetIndex(FeedbackVectorICSlot(0)); |
69 CHECK_EQ(index, | 63 CHECK_EQ(index, |
70 TypeFeedbackVector::kReservedIndexCount + metadata_length + 3); | 64 TypeFeedbackVector::kReservedIndexCount + metadata_length + 3); |
71 CHECK(FeedbackVectorICSlot(0) == vector->ToICSlot(index)); | 65 CHECK(FeedbackVectorICSlot(0) == vector->ToICSlot(index)); |
72 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length + 3 + | 66 CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length + 3 + |
73 5 * TypeFeedbackVector::elements_per_ic_slot(), | 67 5 * TypeFeedbackVector::elements_per_ic_slot(), |
74 vector->length()); | 68 vector->length()); |
75 } | 69 } |
76 | 70 |
77 | 71 |
78 // IC slots need an encoding to recognize what is in there. | 72 // IC slots need an encoding to recognize what is in there. |
79 TEST(VectorICMetadata) { | 73 TEST(VectorICMetadata) { |
80 LocalContext context; | 74 LocalContext context; |
81 v8::HandleScope scope(context->GetIsolate()); | 75 v8::HandleScope scope(context->GetIsolate()); |
82 if (!FLAG_vector_ics) { | |
83 // If FLAG_vector_ics is false, we only store CALL_ICs in the vector, so | |
84 // there is no need for metadata to describe the slots. | |
85 return; | |
86 } | |
87 Isolate* isolate = CcTest::i_isolate(); | 76 Isolate* isolate = CcTest::i_isolate(); |
88 Factory* factory = isolate->factory(); | 77 Factory* factory = isolate->factory(); |
89 Zone* zone = isolate->runtime_zone(); | 78 Zone* zone = isolate->runtime_zone(); |
90 | 79 |
91 ZoneFeedbackVectorSpec spec(zone, 10, 3 * 10); | 80 ZoneFeedbackVectorSpec spec(zone, 10, 3 * 10); |
92 // Set metadata. | 81 // Set metadata. |
93 for (int i = 0; i < 30; i++) { | 82 for (int i = 0; i < 30; i++) { |
94 Code::Kind kind; | 83 Code::Kind kind; |
95 if (i % 3 == 0) { | 84 if (i % 3 == 0) { |
96 kind = Code::CALL_IC; | 85 kind = Code::CALL_IC; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 CompileRun("f(Array)"); | 241 CompileRun("f(Array)"); |
253 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 242 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
254 CHECK(nexus.GetFeedback()->IsAllocationSite()); | 243 CHECK(nexus.GetFeedback()->IsAllocationSite()); |
255 | 244 |
256 heap->CollectAllGarbage(); | 245 heap->CollectAllGarbage(); |
257 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 246 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
258 } | 247 } |
259 | 248 |
260 | 249 |
261 TEST(VectorLoadICStates) { | 250 TEST(VectorLoadICStates) { |
262 if (i::FLAG_always_opt || !i::FLAG_vector_ics) return; | 251 if (i::FLAG_always_opt) return; |
263 CcTest::InitializeVM(); | 252 CcTest::InitializeVM(); |
264 LocalContext context; | 253 LocalContext context; |
265 v8::HandleScope scope(context->GetIsolate()); | 254 v8::HandleScope scope(context->GetIsolate()); |
266 Isolate* isolate = CcTest::i_isolate(); | 255 Isolate* isolate = CcTest::i_isolate(); |
267 Heap* heap = isolate->heap(); | 256 Heap* heap = isolate->heap(); |
268 | 257 |
269 // Make sure function f has a call that uses a type feedback slot. | 258 // Make sure function f has a call that uses a type feedback slot. |
270 CompileRun( | 259 CompileRun( |
271 "var o = { foo: 3 };" | 260 "var o = { foo: 3 };" |
272 "function f(a) { return a.foo; } f(o);"); | 261 "function f(a) { return a.foo; } f(o);"); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); | 295 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); |
307 CHECK(!nexus.FindFirstMap()); | 296 CHECK(!nexus.FindFirstMap()); |
308 | 297 |
309 // After a collection, state should not be reset to PREMONOMORPHIC. | 298 // After a collection, state should not be reset to PREMONOMORPHIC. |
310 heap->CollectAllGarbage(); | 299 heap->CollectAllGarbage(); |
311 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); | 300 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); |
312 } | 301 } |
313 | 302 |
314 | 303 |
315 TEST(VectorLoadICSlotSharing) { | 304 TEST(VectorLoadICSlotSharing) { |
316 if (i::FLAG_always_opt || !i::FLAG_vector_ics) return; | 305 if (i::FLAG_always_opt) return; |
317 CcTest::InitializeVM(); | 306 CcTest::InitializeVM(); |
318 LocalContext context; | 307 LocalContext context; |
319 v8::HandleScope scope(context->GetIsolate()); | 308 v8::HandleScope scope(context->GetIsolate()); |
320 Isolate* isolate = CcTest::i_isolate(); | 309 Isolate* isolate = CcTest::i_isolate(); |
321 | 310 |
322 // Function f has 3 LoadICs, one for each o, but the ICs share the same | 311 // Function f has 3 LoadICs, one for each o, but the ICs share the same |
323 // feedback vector IC slot. | 312 // feedback vector IC slot. |
324 CompileRun( | 313 CompileRun( |
325 "var o = 10;" | 314 "var o = 10;" |
326 "function f() {" | 315 "function f() {" |
327 " var x = o + 10;" | 316 " var x = o + 10;" |
328 " return o + x + o;" | 317 " return o + x + o;" |
329 "}" | 318 "}" |
330 "f();"); | 319 "f();"); |
331 Handle<JSFunction> f = v8::Utils::OpenHandle( | 320 Handle<JSFunction> f = v8::Utils::OpenHandle( |
332 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); | 321 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))); |
333 // There should be one IC slot. | 322 // There should be one IC slot. |
334 Handle<TypeFeedbackVector> feedback_vector = | 323 Handle<TypeFeedbackVector> feedback_vector = |
335 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 324 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); |
336 CHECK_EQ(1, feedback_vector->ICSlots()); | 325 CHECK_EQ(1, feedback_vector->ICSlots()); |
337 FeedbackVectorICSlot slot(0); | 326 FeedbackVectorICSlot slot(0); |
338 LoadICNexus nexus(feedback_vector, slot); | 327 LoadICNexus nexus(feedback_vector, slot); |
339 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 328 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
340 } | 329 } |
341 | 330 |
342 | 331 |
343 TEST(VectorLoadICOnSmi) { | 332 TEST(VectorLoadICOnSmi) { |
344 if (i::FLAG_always_opt || !i::FLAG_vector_ics) return; | 333 if (i::FLAG_always_opt) return; |
345 CcTest::InitializeVM(); | 334 CcTest::InitializeVM(); |
346 LocalContext context; | 335 LocalContext context; |
347 v8::HandleScope scope(context->GetIsolate()); | 336 v8::HandleScope scope(context->GetIsolate()); |
348 Isolate* isolate = CcTest::i_isolate(); | 337 Isolate* isolate = CcTest::i_isolate(); |
349 Heap* heap = isolate->heap(); | 338 Heap* heap = isolate->heap(); |
350 | 339 |
351 // Make sure function f has a call that uses a type feedback slot. | 340 // Make sure function f has a call that uses a type feedback slot. |
352 CompileRun( | 341 CompileRun( |
353 "var o = { foo: 3 };" | 342 "var o = { foo: 3 };" |
354 "function f(a) { return a.foo; } f(o);"); | 343 "function f(a) { return a.foo; } f(o);"); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 CHECK(number_map_found && o_map_found); | 379 CHECK(number_map_found && o_map_found); |
391 | 380 |
392 // The degree of polymorphism doesn't change. | 381 // The degree of polymorphism doesn't change. |
393 CompileRun("f(100)"); | 382 CompileRun("f(100)"); |
394 CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback()); | 383 CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback()); |
395 MapHandleList maps2; | 384 MapHandleList maps2; |
396 nexus.FindAllMaps(&maps2); | 385 nexus.FindAllMaps(&maps2); |
397 CHECK_EQ(2, maps2.length()); | 386 CHECK_EQ(2, maps2.length()); |
398 } | 387 } |
399 } | 388 } |
OLD | NEW |