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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 CHECK(vector->Get(helper.slot(2))->IsAllocationSite()); | 192 CHECK(vector->Get(helper.slot(2))->IsAllocationSite()); |
193 } | 193 } |
194 | 194 |
195 | 195 |
196 TEST(VectorCallICStates) { | 196 TEST(VectorCallICStates) { |
197 if (i::FLAG_always_opt) return; | 197 if (i::FLAG_always_opt) return; |
198 CcTest::InitializeVM(); | 198 CcTest::InitializeVM(); |
199 LocalContext context; | 199 LocalContext context; |
200 v8::HandleScope scope(context->GetIsolate()); | 200 v8::HandleScope scope(context->GetIsolate()); |
201 Isolate* isolate = CcTest::i_isolate(); | 201 Isolate* isolate = CcTest::i_isolate(); |
202 Heap* heap = isolate->heap(); | |
203 | |
204 // Make sure function f has a call that uses a type feedback slot. | 202 // Make sure function f has a call that uses a type feedback slot. |
205 CompileRun( | 203 CompileRun( |
206 "function foo() { return 17; }" | 204 "function foo() { return 17; }" |
207 "function f(a) { a(); } f(foo);"); | 205 "function f(a) { a(); } f(foo);"); |
208 Handle<JSFunction> f = GetFunction("f"); | 206 Handle<JSFunction> f = GetFunction("f"); |
209 // There should be one IC. | 207 // There should be one IC. |
210 Handle<TypeFeedbackVector> feedback_vector = | 208 Handle<TypeFeedbackVector> feedback_vector = |
211 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); | 209 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
212 FeedbackVectorSlot slot(0); | 210 FeedbackVectorSlot slot(0); |
213 CallICNexus nexus(feedback_vector, slot); | 211 CallICNexus nexus(feedback_vector, slot); |
214 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 212 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
215 // CallIC doesn't return map feedback. | 213 // CallIC doesn't return map feedback. |
216 CHECK(!nexus.FindFirstMap()); | 214 CHECK(!nexus.FindFirstMap()); |
217 | 215 |
218 CompileRun("f(function() { return 16; })"); | 216 CompileRun("f(function() { return 16; })"); |
219 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); | 217 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); |
220 | 218 |
221 // After a collection, state should remain GENERIC. | 219 // After a collection, state should remain GENERIC. |
222 heap->CollectAllGarbage(); | 220 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
223 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); | 221 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); |
224 } | 222 } |
225 | 223 |
226 TEST(VectorCallFeedbackForArray) { | 224 TEST(VectorCallFeedbackForArray) { |
227 if (i::FLAG_always_opt) return; | 225 if (i::FLAG_always_opt) return; |
228 CcTest::InitializeVM(); | 226 CcTest::InitializeVM(); |
229 LocalContext context; | 227 LocalContext context; |
230 v8::HandleScope scope(context->GetIsolate()); | 228 v8::HandleScope scope(context->GetIsolate()); |
231 Isolate* isolate = CcTest::i_isolate(); | 229 Isolate* isolate = CcTest::i_isolate(); |
232 Heap* heap = isolate->heap(); | |
233 | |
234 // Make sure function f has a call that uses a type feedback slot. | 230 // Make sure function f has a call that uses a type feedback slot. |
235 CompileRun( | 231 CompileRun( |
236 "function foo() { return 17; }" | 232 "function foo() { return 17; }" |
237 "function f(a) { a(); } f(Array);"); | 233 "function f(a) { a(); } f(Array);"); |
238 Handle<JSFunction> f = GetFunction("f"); | 234 Handle<JSFunction> f = GetFunction("f"); |
239 // There should be one IC. | 235 // There should be one IC. |
240 Handle<TypeFeedbackVector> feedback_vector = | 236 Handle<TypeFeedbackVector> feedback_vector = |
241 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); | 237 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
242 FeedbackVectorSlot slot(0); | 238 FeedbackVectorSlot slot(0); |
243 CallICNexus nexus(feedback_vector, slot); | 239 CallICNexus nexus(feedback_vector, slot); |
244 | 240 |
245 // A call to Array is special, it contains an AllocationSite as feedback. | 241 // A call to Array is special, it contains an AllocationSite as feedback. |
246 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 242 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
247 CHECK(nexus.GetFeedback()->IsAllocationSite()); | 243 CHECK(nexus.GetFeedback()->IsAllocationSite()); |
248 | 244 |
249 heap->CollectAllGarbage(); | 245 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
250 // It should stay monomorphic even after a GC. | 246 // It should stay monomorphic even after a GC. |
251 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 247 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
252 } | 248 } |
253 | 249 |
254 TEST(VectorCallCounts) { | 250 TEST(VectorCallCounts) { |
255 if (i::FLAG_always_opt) return; | 251 if (i::FLAG_always_opt) return; |
256 CcTest::InitializeVM(); | 252 CcTest::InitializeVM(); |
257 LocalContext context; | 253 LocalContext context; |
258 v8::HandleScope scope(context->GetIsolate()); | 254 v8::HandleScope scope(context->GetIsolate()); |
259 Isolate* isolate = CcTest::i_isolate(); | 255 Isolate* isolate = CcTest::i_isolate(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 CHECK(feedback_vector->Get(cslot)->IsSmi()); | 293 CHECK(feedback_vector->Get(cslot)->IsSmi()); |
298 CHECK_EQ(3, Smi::cast(feedback_vector->Get(cslot))->value()); | 294 CHECK_EQ(3, Smi::cast(feedback_vector->Get(cslot))->value()); |
299 } | 295 } |
300 | 296 |
301 TEST(VectorLoadICStates) { | 297 TEST(VectorLoadICStates) { |
302 if (i::FLAG_always_opt) return; | 298 if (i::FLAG_always_opt) return; |
303 CcTest::InitializeVM(); | 299 CcTest::InitializeVM(); |
304 LocalContext context; | 300 LocalContext context; |
305 v8::HandleScope scope(context->GetIsolate()); | 301 v8::HandleScope scope(context->GetIsolate()); |
306 Isolate* isolate = CcTest::i_isolate(); | 302 Isolate* isolate = CcTest::i_isolate(); |
307 Heap* heap = isolate->heap(); | |
308 | 303 |
309 // Make sure function f has a call that uses a type feedback slot. | 304 // Make sure function f has a call that uses a type feedback slot. |
310 CompileRun( | 305 CompileRun( |
311 "var o = { foo: 3 };" | 306 "var o = { foo: 3 };" |
312 "function f(a) { return a.foo; } f(o);"); | 307 "function f(a) { return a.foo; } f(o);"); |
313 Handle<JSFunction> f = GetFunction("f"); | 308 Handle<JSFunction> f = GetFunction("f"); |
314 // There should be one IC. | 309 // There should be one IC. |
315 Handle<TypeFeedbackVector> feedback_vector = | 310 Handle<TypeFeedbackVector> feedback_vector = |
316 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); | 311 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
317 FeedbackVectorSlot slot(0); | 312 FeedbackVectorSlot slot(0); |
(...skipping 23 matching lines...) Expand all Loading... |
341 MapHandleList maps; | 336 MapHandleList maps; |
342 nexus.FindAllMaps(&maps); | 337 nexus.FindAllMaps(&maps); |
343 CHECK_EQ(4, maps.length()); | 338 CHECK_EQ(4, maps.length()); |
344 | 339 |
345 // Finally driven megamorphic. | 340 // Finally driven megamorphic. |
346 CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })"); | 341 CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })"); |
347 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); | 342 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); |
348 CHECK(!nexus.FindFirstMap()); | 343 CHECK(!nexus.FindFirstMap()); |
349 | 344 |
350 // After a collection, state should not be reset to PREMONOMORPHIC. | 345 // After a collection, state should not be reset to PREMONOMORPHIC. |
351 heap->CollectAllGarbage(); | 346 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
352 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); | 347 CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback()); |
353 } | 348 } |
354 | 349 |
355 | 350 |
356 TEST(VectorLoadICSlotSharing) { | 351 TEST(VectorLoadICSlotSharing) { |
357 if (i::FLAG_always_opt) return; | 352 if (i::FLAG_always_opt) return; |
358 CcTest::InitializeVM(); | 353 CcTest::InitializeVM(); |
359 LocalContext context; | 354 LocalContext context; |
360 v8::HandleScope scope(context->GetIsolate()); | 355 v8::HandleScope scope(context->GetIsolate()); |
361 Isolate* isolate = CcTest::i_isolate(); | 356 Isolate* isolate = CcTest::i_isolate(); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 // There should be one IC slot. | 571 // There should be one IC slot. |
577 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); | 572 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
578 FeedbackVectorHelper helper(feedback_vector); | 573 FeedbackVectorHelper helper(feedback_vector); |
579 CHECK_EQ(1, helper.slot_count()); | 574 CHECK_EQ(1, helper.slot_count()); |
580 FeedbackVectorSlot slot(0); | 575 FeedbackVectorSlot slot(0); |
581 StoreICNexus nexus(feedback_vector, slot); | 576 StoreICNexus nexus(feedback_vector, slot); |
582 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 577 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
583 } | 578 } |
584 | 579 |
585 } // namespace | 580 } // namespace |
OLD | NEW |