Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(417)

Side by Side Diff: test/cctest/test-heap.cc

Issue 754303003: Flesh out vector ic state query and set mechanisms. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/test-feedback-vector.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3277 matching lines...) Expand 10 before | Expand all | Expand 10 after
3288 3288
3289 Handle<JSFunction> f = 3289 Handle<JSFunction> f =
3290 v8::Utils::OpenHandle( 3290 v8::Utils::OpenHandle(
3291 *v8::Handle<v8::Function>::Cast( 3291 *v8::Handle<v8::Function>::Cast(
3292 CcTest::global()->Get(v8_str("f")))); 3292 CcTest::global()->Get(v8_str("f"))));
3293 3293
3294 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); 3294 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
3295 3295
3296 int expected_slots = 2; 3296 int expected_slots = 2;
3297 CHECK_EQ(expected_slots, feedback_vector->ICSlots()); 3297 CHECK_EQ(expected_slots, feedback_vector->ICSlots());
3298 for (int i = 0; i < expected_slots; i++) { 3298 int slot1 = 0;
3299 CHECK(feedback_vector->Get(FeedbackVectorICSlot(i))->IsJSFunction()); 3299 int slot2 = 1;
3300 } 3300 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot1))->IsJSFunction());
3301 CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot2))->IsJSFunction());
3301 3302
3302 SimulateIncrementalMarking(CcTest::heap()); 3303 SimulateIncrementalMarking(CcTest::heap());
3303 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3304 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3304 3305
3305 CHECK_EQ(expected_slots, feedback_vector->ICSlots()); 3306 CHECK_EQ(feedback_vector->Get(FeedbackVectorICSlot(slot1)),
3306 for (int i = 0; i < expected_slots; i++) { 3307 *TypeFeedbackVector::UninitializedSentinel(CcTest::i_isolate()));
3307 CHECK_EQ(feedback_vector->Get(FeedbackVectorICSlot(i)), 3308 CHECK_EQ(feedback_vector->Get(FeedbackVectorICSlot(slot2)),
3308 *TypeFeedbackVector::UninitializedSentinel(CcTest::i_isolate())); 3309 *TypeFeedbackVector::UninitializedSentinel(CcTest::i_isolate()));
3309 }
3310 } 3310 }
3311 3311
3312 3312
3313 static Code* FindFirstIC(Code* code, Code::Kind kind) { 3313 static Code* FindFirstIC(Code* code, Code::Kind kind) {
3314 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 3314 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
3315 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | 3315 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
3316 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); 3316 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
3317 for (RelocIterator it(code, mask); !it.done(); it.next()) { 3317 for (RelocIterator it(code, mask); !it.done(); it.next()) {
3318 RelocInfo* info = it.rinfo(); 3318 RelocInfo* info = it.rinfo();
3319 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); 3319 Code* target = Code::GetCodeFromTargetAddress(info->target_address());
3320 if (target->is_inline_cache_stub() && target->kind() == kind) { 3320 if (target->is_inline_cache_stub() && target->kind() == kind) {
3321 return target; 3321 return target;
3322 } 3322 }
3323 } 3323 }
3324 return NULL; 3324 return NULL;
3325 } 3325 }
3326 3326
3327 3327
3328 static void CheckVectorIC(Handle<JSFunction> f, int ic_slot_index,
3329 InlineCacheState desired_state) {
3330 Handle<TypeFeedbackVector> vector =
3331 Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
3332 FeedbackVectorICSlot slot(ic_slot_index);
3333 LoadICNexus nexus(vector, slot);
3334 CHECK(nexus.StateFromFeedback() == desired_state);
3335 }
3336
3337
3338 static void CheckVectorICCleared(Handle<JSFunction> f, int ic_slot_index) {
3339 Handle<TypeFeedbackVector> vector =
3340 Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
3341 FeedbackVectorICSlot slot(ic_slot_index);
3342 LoadICNexus nexus(vector, slot);
3343 CHECK(IC::IsCleared(&nexus));
3344 }
3345
3346
3328 TEST(IncrementalMarkingPreservesMonomorphicIC) { 3347 TEST(IncrementalMarkingPreservesMonomorphicIC) {
3329 if (i::FLAG_always_opt) return; 3348 if (i::FLAG_always_opt) return;
3330 CcTest::InitializeVM(); 3349 CcTest::InitializeVM();
3331 v8::HandleScope scope(CcTest::isolate()); 3350 v8::HandleScope scope(CcTest::isolate());
3332 3351
3333 // Prepare function f that contains a monomorphic IC for object 3352 // Prepare function f that contains a monomorphic IC for object
3334 // originating from the same native context. 3353 // originating from the same native context.
3335 CompileRun("function fun() { this.x = 1; }; var obj = new fun();" 3354 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
3336 "function f(o) { return o.x; } f(obj); f(obj);"); 3355 "function f(o) { return o.x; } f(obj); f(obj);");
3337 Handle<JSFunction> f = 3356 Handle<JSFunction> f =
3338 v8::Utils::OpenHandle( 3357 v8::Utils::OpenHandle(
3339 *v8::Handle<v8::Function>::Cast( 3358 *v8::Handle<v8::Function>::Cast(
3340 CcTest::global()->Get(v8_str("f")))); 3359 CcTest::global()->Get(v8_str("f"))));
3341 3360
3342 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3361 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3343 CHECK(ic_before->ic_state() == MONOMORPHIC); 3362 if (FLAG_vector_ics) {
3363 CheckVectorIC(f, 0, MONOMORPHIC);
3364 CHECK(ic_before->ic_state() == DEFAULT);
3365 } else {
3366 CHECK(ic_before->ic_state() == MONOMORPHIC);
3367 }
3344 3368
3345 SimulateIncrementalMarking(CcTest::heap()); 3369 SimulateIncrementalMarking(CcTest::heap());
3346 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3370 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3347 3371
3348 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3372 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3349 CHECK(ic_after->ic_state() == MONOMORPHIC); 3373 if (FLAG_vector_ics) {
3374 CheckVectorIC(f, 0, MONOMORPHIC);
3375 CHECK(ic_after->ic_state() == DEFAULT);
3376 } else {
3377 CHECK(ic_after->ic_state() == MONOMORPHIC);
3378 }
3350 } 3379 }
3351 3380
3352 3381
3353 TEST(IncrementalMarkingClearsMonomorphicIC) { 3382 TEST(IncrementalMarkingClearsMonomorphicIC) {
3354 if (i::FLAG_always_opt) return; 3383 if (i::FLAG_always_opt) return;
3355 CcTest::InitializeVM(); 3384 CcTest::InitializeVM();
3356 v8::HandleScope scope(CcTest::isolate()); 3385 v8::HandleScope scope(CcTest::isolate());
3357 v8::Local<v8::Value> obj1; 3386 v8::Local<v8::Value> obj1;
3358 3387
3359 { 3388 {
3360 LocalContext env; 3389 LocalContext env;
3361 CompileRun("function fun() { this.x = 1; }; var obj = new fun();"); 3390 CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
3362 obj1 = env->Global()->Get(v8_str("obj")); 3391 obj1 = env->Global()->Get(v8_str("obj"));
3363 } 3392 }
3364 3393
3365 // Prepare function f that contains a monomorphic IC for object 3394 // Prepare function f that contains a monomorphic IC for object
3366 // originating from a different native context. 3395 // originating from a different native context.
3367 CcTest::global()->Set(v8_str("obj1"), obj1); 3396 CcTest::global()->Set(v8_str("obj1"), obj1);
3368 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);"); 3397 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1);");
3369 Handle<JSFunction> f = 3398 Handle<JSFunction> f =
3370 v8::Utils::OpenHandle( 3399 v8::Utils::OpenHandle(
3371 *v8::Handle<v8::Function>::Cast( 3400 *v8::Handle<v8::Function>::Cast(
3372 CcTest::global()->Get(v8_str("f")))); 3401 CcTest::global()->Get(v8_str("f"))));
3373 3402
3374 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3403 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3375 CHECK(ic_before->ic_state() == MONOMORPHIC); 3404 if (FLAG_vector_ics) {
3405 CheckVectorIC(f, 0, MONOMORPHIC);
3406 CHECK(ic_before->ic_state() == DEFAULT);
3407 } else {
3408 CHECK(ic_before->ic_state() == MONOMORPHIC);
3409 }
3376 3410
3377 // Fire context dispose notification. 3411 // Fire context dispose notification.
3378 CcTest::isolate()->ContextDisposedNotification(); 3412 CcTest::isolate()->ContextDisposedNotification();
3379 SimulateIncrementalMarking(CcTest::heap()); 3413 SimulateIncrementalMarking(CcTest::heap());
3380 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3414 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3381 3415
3382 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3416 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3383 CHECK(IC::IsCleared(ic_after)); 3417 if (FLAG_vector_ics) {
3418 CheckVectorICCleared(f, 0);
3419 CHECK(ic_after->ic_state() == DEFAULT);
3420 } else {
3421 CHECK(IC::IsCleared(ic_after));
3422 }
3384 } 3423 }
3385 3424
3386 3425
3387 TEST(IncrementalMarkingClearsPolymorphicIC) { 3426 TEST(IncrementalMarkingClearsPolymorphicIC) {
3388 if (i::FLAG_always_opt) return; 3427 if (i::FLAG_always_opt) return;
3389 CcTest::InitializeVM(); 3428 CcTest::InitializeVM();
3390 v8::HandleScope scope(CcTest::isolate()); 3429 v8::HandleScope scope(CcTest::isolate());
3391 v8::Local<v8::Value> obj1, obj2; 3430 v8::Local<v8::Value> obj1, obj2;
3392 3431
3393 { 3432 {
(...skipping 12 matching lines...) Expand all
3406 // originating from two different native contexts. 3445 // originating from two different native contexts.
3407 CcTest::global()->Set(v8_str("obj1"), obj1); 3446 CcTest::global()->Set(v8_str("obj1"), obj1);
3408 CcTest::global()->Set(v8_str("obj2"), obj2); 3447 CcTest::global()->Set(v8_str("obj2"), obj2);
3409 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);"); 3448 CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);");
3410 Handle<JSFunction> f = 3449 Handle<JSFunction> f =
3411 v8::Utils::OpenHandle( 3450 v8::Utils::OpenHandle(
3412 *v8::Handle<v8::Function>::Cast( 3451 *v8::Handle<v8::Function>::Cast(
3413 CcTest::global()->Get(v8_str("f")))); 3452 CcTest::global()->Get(v8_str("f"))));
3414 3453
3415 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3454 Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3416 CHECK(ic_before->ic_state() == POLYMORPHIC); 3455 if (FLAG_vector_ics) {
3456 CheckVectorIC(f, 0, POLYMORPHIC);
3457 CHECK(ic_before->ic_state() == DEFAULT);
3458 } else {
3459 CHECK(ic_before->ic_state() == POLYMORPHIC);
3460 }
3417 3461
3418 // Fire context dispose notification. 3462 // Fire context dispose notification.
3419 CcTest::isolate()->ContextDisposedNotification(); 3463 CcTest::isolate()->ContextDisposedNotification();
3420 SimulateIncrementalMarking(CcTest::heap()); 3464 SimulateIncrementalMarking(CcTest::heap());
3421 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 3465 CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
3422 3466
3423 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC); 3467 Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
3424 CHECK(IC::IsCleared(ic_after)); 3468 if (FLAG_vector_ics) {
3469 CheckVectorICCleared(f, 0);
3470 CHECK(ic_before->ic_state() == DEFAULT);
3471 } else {
3472 CHECK(IC::IsCleared(ic_after));
3473 }
3425 } 3474 }
3426 3475
3427 3476
3428 class SourceResource : public v8::String::ExternalOneByteStringResource { 3477 class SourceResource : public v8::String::ExternalOneByteStringResource {
3429 public: 3478 public:
3430 explicit SourceResource(const char* data) 3479 explicit SourceResource(const char* data)
3431 : data_(data), length_(strlen(data)) { } 3480 : data_(data), length_(strlen(data)) { }
3432 3481
3433 virtual void Dispose() { 3482 virtual void Dispose() {
3434 i::DeleteArray(data_); 3483 i::DeleteArray(data_);
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
4040 CcTest::global()->Get(v8_str("bar")))); 4089 CcTest::global()->Get(v8_str("bar"))));
4041 CHECK_EQ(bar_handle->code(), function_bar); 4090 CHECK_EQ(bar_handle->code(), function_bar);
4042 } 4091 }
4043 4092
4044 // Now make sure that a gc should get rid of the function, even though we 4093 // Now make sure that a gc should get rid of the function, even though we
4045 // still have the allocation site alive. 4094 // still have the allocation site alive.
4046 for (int i = 0; i < 4; i++) { 4095 for (int i = 0; i < 4; i++) {
4047 heap->CollectAllGarbage(Heap::kNoGCFlags); 4096 heap->CollectAllGarbage(Heap::kNoGCFlags);
4048 } 4097 }
4049 4098
4099 // TODO(mvstanton): this test fails when FLAG_vector_ics is true because
4100 // monomorphic load ics are preserved, but also strongly walked. They
4101 // end up keeping function bar alive.
4102
4050 // The site still exists because of our global handle, but the code is no 4103 // The site still exists because of our global handle, but the code is no
4051 // longer referred to by dependent_code(). 4104 // longer referred to by dependent_code().
4052 DependentCode::GroupStartIndexes starts(site->dependent_code()); 4105 DependentCode::GroupStartIndexes starts(site->dependent_code());
4053 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); 4106 int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup);
4054 CHECK(!(site->dependent_code()->is_code_at(index))); 4107 CHECK(!(site->dependent_code()->is_code_at(index)));
4055 } 4108 }
4056 4109
4057 4110
4058 TEST(CellsInOptimizedCodeAreWeak) { 4111 TEST(CellsInOptimizedCodeAreWeak) {
4059 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; 4112 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
4304 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC); 4357 garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC);
4305 Heap* heap = CcTest::i_isolate()->heap(); 4358 Heap* heap = CcTest::i_isolate()->heap();
4306 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 4359 heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
4307 CHECK(weak_ic_cleared); 4360 CHECK(weak_ic_cleared);
4308 } 4361 }
4309 4362
4310 4363
4311 // Each of the following "weak IC" tests creates an IC that embeds a map with 4364 // Each of the following "weak IC" tests creates an IC that embeds a map with
4312 // the prototype pointing to _proto_ and checks that the _proto_ dies on GC. 4365 // the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
4313 TEST(WeakMapInMonomorphicLoadIC) { 4366 TEST(WeakMapInMonomorphicLoadIC) {
4367 // TODO(mvstanton): vector ics need weak support!
4368 if (FLAG_vector_ics) return;
4314 CheckWeakness("function loadIC(obj) {" 4369 CheckWeakness("function loadIC(obj) {"
4315 " return obj.name;" 4370 " return obj.name;"
4316 "}" 4371 "}"
4317 " (function() {" 4372 " (function() {"
4318 " var proto = {'name' : 'weak'};" 4373 " var proto = {'name' : 'weak'};"
4319 " var obj = Object.create(proto);" 4374 " var obj = Object.create(proto);"
4320 " loadIC(obj);" 4375 " loadIC(obj);"
4321 " loadIC(obj);" 4376 " loadIC(obj);"
4322 " loadIC(obj);" 4377 " loadIC(obj);"
4323 " return proto;" 4378 " return proto;"
4324 " })();"); 4379 " })();");
4325 } 4380 }
4326 4381
4327 4382
4328 TEST(WeakMapInMonomorphicKeyedLoadIC) { 4383 TEST(WeakMapInMonomorphicKeyedLoadIC) {
4384 // TODO(mvstanton): vector ics need weak support!
4385 if (FLAG_vector_ics) return;
4329 CheckWeakness("function keyedLoadIC(obj, field) {" 4386 CheckWeakness("function keyedLoadIC(obj, field) {"
4330 " return obj[field];" 4387 " return obj[field];"
4331 "}" 4388 "}"
4332 " (function() {" 4389 " (function() {"
4333 " var proto = {'name' : 'weak'};" 4390 " var proto = {'name' : 'weak'};"
4334 " var obj = Object.create(proto);" 4391 " var obj = Object.create(proto);"
4335 " keyedLoadIC(obj, 'name');" 4392 " keyedLoadIC(obj, 'name');"
4336 " keyedLoadIC(obj, 'name');" 4393 " keyedLoadIC(obj, 'name');"
4337 " keyedLoadIC(obj, 'name');" 4394 " keyedLoadIC(obj, 'name');"
4338 " return proto;" 4395 " return proto;"
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
4755 #ifdef DEBUG 4812 #ifdef DEBUG
4756 TEST(PathTracer) { 4813 TEST(PathTracer) {
4757 CcTest::InitializeVM(); 4814 CcTest::InitializeVM();
4758 v8::HandleScope scope(CcTest::isolate()); 4815 v8::HandleScope scope(CcTest::isolate());
4759 4816
4760 v8::Local<v8::Value> result = CompileRun("'abc'"); 4817 v8::Local<v8::Value> result = CompileRun("'abc'");
4761 Handle<Object> o = v8::Utils::OpenHandle(*result); 4818 Handle<Object> o = v8::Utils::OpenHandle(*result);
4762 CcTest::i_isolate()->heap()->TracePathToObject(*o); 4819 CcTest::i_isolate()->heap()->TracePathToObject(*o);
4763 } 4820 }
4764 #endif // DEBUG 4821 #endif // DEBUG
OLDNEW
« no previous file with comments | « test/cctest/test-feedback-vector.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698