| 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 |