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

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

Issue 2626863004: Revert of [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: Created 3 years, 11 months 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 | « src/type-feedback-vector.cc ('k') | test/cctest/test-feedback-vector.cc » ('j') | 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 4278 matching lines...) Expand 10 before | Expand all | Expand 10 after
4289 CompileRun("function g() { return 2 }" 4289 CompileRun("function g() { return 2 }"
4290 "g(); %OptimizeFunctionOnNextCall(g); g();"); 4290 "g(); %OptimizeFunctionOnNextCall(g); g();");
4291 4291
4292 Handle<JSFunction> g = Handle<JSFunction>::cast( 4292 Handle<JSFunction> g = Handle<JSFunction>::cast(
4293 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 4293 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4294 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); 4294 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked())));
4295 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); 4295 code = inner_scope.CloseAndEscape(handle(g->code(), isolate));
4296 if (!code->is_optimized_code()) return; 4296 if (!code->is_optimized_code()) return;
4297 } 4297 }
4298 4298
4299 Handle<TypeFeedbackVector> vector =
4300 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
4301 Handle<LiteralsArray> lit =
4302 LiteralsArray::New(isolate, vector, shared->num_literals());
4299 Handle<Context> context(isolate->context()); 4303 Handle<Context> context(isolate->context());
4300 4304
4301 // Add the new code several times to the optimized code map and also set an 4305 // Add the new code several times to the optimized code map and also set an
4302 // allocation timeout so that expanding the code map will trigger a GC. 4306 // allocation timeout so that expanding the code map will trigger a GC.
4303 heap->set_allocation_timeout(5); 4307 heap->set_allocation_timeout(5);
4304 FLAG_gc_interval = 1000; 4308 FLAG_gc_interval = 1000;
4305 for (int i = 0; i < 10; ++i) { 4309 for (int i = 0; i < 10; ++i) {
4306 BailoutId id = BailoutId(i); 4310 BailoutId id = BailoutId(i);
4307 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, id); 4311 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);
4308 } 4312 }
4309 } 4313 }
4310 #endif // DEBUG 4314 #endif // DEBUG
4311 4315
4316
4317 TEST(Regress514122) {
4318 if (!i::FLAG_incremental_marking) return;
4319 i::FLAG_allow_natives_syntax = true;
4320 CcTest::InitializeVM();
4321 Isolate* isolate = CcTest::i_isolate();
4322 LocalContext env;
4323 Heap* heap = isolate->heap();
4324 HandleScope scope(isolate);
4325
4326 // Perfrom one initial GC to enable code flushing.
4327 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
4328
4329 // Prepare function whose optimized code map we can use.
4330 Handle<SharedFunctionInfo> shared;
4331 {
4332 HandleScope inner_scope(isolate);
4333 CompileRun("function f() { return 1 }"
4334 "f(); %OptimizeFunctionOnNextCall(f); f();");
4335
4336 Handle<JSFunction> f = Handle<JSFunction>::cast(
4337 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4338 CcTest::global()->Get(env.local(), v8_str("f")).ToLocalChecked())));
4339 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate));
4340 CompileRun("f = null");
4341 }
4342
4343 // Prepare optimized code that we can use.
4344 Handle<Code> code;
4345 {
4346 HandleScope inner_scope(isolate);
4347 CompileRun("function g() { return 2 }"
4348 "g(); %OptimizeFunctionOnNextCall(g); g();");
4349
4350 Handle<JSFunction> g = Handle<JSFunction>::cast(
4351 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4352 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked())));
4353 code = inner_scope.CloseAndEscape(handle(g->code(), isolate));
4354 if (!code->is_optimized_code()) return;
4355 }
4356
4357 Handle<TypeFeedbackVector> vector =
4358 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
4359 Handle<LiteralsArray> lit =
4360 LiteralsArray::New(isolate, vector, shared->num_literals(), TENURED);
4361 Handle<Context> context(isolate->context());
4362
4363 // Add the code several times to the optimized code map.
4364 for (int i = 0; i < 3; ++i) {
4365 HandleScope inner_scope(isolate);
4366 BailoutId id = BailoutId(i);
4367 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);
4368 }
4369 shared->optimized_code_map()->Print();
4370
4371 // Add the code with a literals array to be evacuated.
4372 Page* evac_page;
4373 {
4374 HandleScope inner_scope(isolate);
4375 AlwaysAllocateScope always_allocate(isolate);
4376 // Make sure literal is placed on an old-space evacuation candidate.
4377 heap::SimulateFullSpace(heap->old_space());
4378
4379 // Make sure there the number of literals is > 0.
4380 Handle<LiteralsArray> lit = LiteralsArray::New(isolate, vector, 23);
4381
4382 evac_page = Page::FromAddress(lit->address());
4383 BailoutId id = BailoutId(100);
4384 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);
4385 }
4386
4387 // Heap is ready, force {lit_page} to become an evacuation candidate and
4388 // simulate incremental marking to enqueue optimized code map.
4389 FLAG_manual_evacuation_candidates_selection = true;
4390 heap::ForceEvacuationCandidate(evac_page);
4391 heap::SimulateIncrementalMarking(heap);
4392
4393 // No matter whether reachable or not, {boomer} is doomed.
4394 Handle<Object> boomer(shared->optimized_code_map(), isolate);
4395
4396 // Add the code several times to the optimized code map. This will leave old
4397 // copies of the optimized code map unreachable but still marked.
4398 for (int i = 3; i < 6; ++i) {
4399 HandleScope inner_scope(isolate);
4400 BailoutId id = BailoutId(i);
4401 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id);
4402 }
4403
4404 // Trigger a GC to flush out the bug.
4405 CcTest::CollectGarbage(i::OLD_SPACE);
4406 boomer->Print();
4407 }
4408
4409
4410 TEST(OptimizedCodeMapReuseEntries) {
4411 i::FLAG_allow_natives_syntax = true;
4412 // BUG(v8:4598): Since TurboFan doesn't treat maps in code weakly, we can't
4413 // run this test.
4414 if (i::FLAG_turbo) return;
4415 CcTest::InitializeVM();
4416 v8::Isolate* v8_isolate = CcTest::isolate();
4417 Isolate* isolate = CcTest::i_isolate();
4418 HandleScope scope(isolate);
4419
4420 // Create 3 contexts, allow the 2nd one to be disposed, and verify that
4421 // a 4th context will re-use the weak slots in the optimized code map
4422 // to hold data, rather than expanding the map.
4423 v8::Local<v8::Context> c1 = v8::Context::New(v8_isolate);
4424 const char* source = "function foo(x) { var l = [1]; return x+l[0]; }";
4425 v8::ScriptCompiler::Source script_source(
4426 v8::String::NewFromUtf8(v8_isolate, source, v8::NewStringType::kNormal)
4427 .ToLocalChecked());
4428 v8::Local<v8::UnboundScript> indep =
4429 v8::ScriptCompiler::CompileUnboundScript(v8_isolate, &script_source)
4430 .ToLocalChecked();
4431 const char* toplevel = "foo(3); %OptimizeFunctionOnNextCall(foo); foo(3);";
4432 // Perfrom one initial GC to enable code flushing.
4433 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
4434
4435 c1->Enter();
4436 indep->BindToCurrentContext()->Run(c1).ToLocalChecked();
4437 CompileRun(toplevel);
4438
4439 Handle<SharedFunctionInfo> shared;
4440 Handle<JSFunction> foo = Handle<JSFunction>::cast(
4441 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
4442 CcTest::global()->Get(c1, v8_str("foo")).ToLocalChecked())));
4443 CHECK(foo->shared()->is_compiled());
4444 shared = handle(foo->shared());
4445 c1->Exit();
4446
4447 {
4448 HandleScope scope(isolate);
4449 v8::Local<v8::Context> c2 = v8::Context::New(v8_isolate);
4450 c2->Enter();
4451 indep->BindToCurrentContext()->Run(c2).ToLocalChecked();
4452 CompileRun(toplevel);
4453 c2->Exit();
4454 }
4455
4456 {
4457 HandleScope scope(isolate);
4458 v8::Local<v8::Context> c3 = v8::Context::New(v8_isolate);
4459 c3->Enter();
4460 indep->BindToCurrentContext()->Run(c3).ToLocalChecked();
4461 CompileRun(toplevel);
4462 c3->Exit();
4463
4464 // Now, collect garbage. Context c2 should have no roots to it, and it's
4465 // entry in the optimized code map should be free for a new context.
4466 for (int i = 0; i < 4; i++) {
4467 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
4468 }
4469
4470 Handle<FixedArray> optimized_code_map =
4471 handle(shared->optimized_code_map());
4472 // There should be 3 entries in the map.
4473 CHECK_EQ(
4474 3, ((optimized_code_map->length() - SharedFunctionInfo::kEntriesStart) /
4475 SharedFunctionInfo::kEntryLength));
4476 // But one of them (formerly for c2) should be cleared.
4477 int cleared_count = 0;
4478 for (int i = SharedFunctionInfo::kEntriesStart;
4479 i < optimized_code_map->length();
4480 i += SharedFunctionInfo::kEntryLength) {
4481 cleared_count +=
4482 WeakCell::cast(
4483 optimized_code_map->get(i + SharedFunctionInfo::kContextOffset))
4484 ->cleared()
4485 ? 1
4486 : 0;
4487 }
4488 CHECK_EQ(1, cleared_count);
4489
4490 // Verify that a new context uses the cleared entry rather than creating a
4491 // new
4492 // optimized code map array.
4493 v8::Local<v8::Context> c4 = v8::Context::New(v8_isolate);
4494 c4->Enter();
4495 indep->BindToCurrentContext()->Run(c4).ToLocalChecked();
4496 CompileRun(toplevel);
4497 c4->Exit();
4498 CHECK_EQ(*optimized_code_map, shared->optimized_code_map());
4499
4500 // Now each entry is in use.
4501 cleared_count = 0;
4502 for (int i = SharedFunctionInfo::kEntriesStart;
4503 i < optimized_code_map->length();
4504 i += SharedFunctionInfo::kEntryLength) {
4505 cleared_count +=
4506 WeakCell::cast(
4507 optimized_code_map->get(i + SharedFunctionInfo::kContextOffset))
4508 ->cleared()
4509 ? 1
4510 : 0;
4511 }
4512 CHECK_EQ(0, cleared_count);
4513 }
4514 }
4515
4516
4312 TEST(Regress513496) { 4517 TEST(Regress513496) {
4313 i::FLAG_allow_natives_syntax = true; 4518 i::FLAG_allow_natives_syntax = true;
4314 CcTest::InitializeVM(); 4519 CcTest::InitializeVM();
4315 Isolate* isolate = CcTest::i_isolate(); 4520 Isolate* isolate = CcTest::i_isolate();
4316 HandleScope scope(isolate); 4521 HandleScope scope(isolate);
4317 4522
4318 // Perfrom one initial GC to enable code flushing. 4523 // Perfrom one initial GC to enable code flushing.
4319 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); 4524 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
4320 4525
4321 // Prepare an optimized closure with containing an inlined function. Then age 4526 // Prepare an optimized closure with containing an inlined function. Then age
(...skipping 25 matching lines...) Expand all
4347 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( 4552 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
4348 *v8::Local<v8::Function>::Cast(CcTest::global() 4553 *v8::Local<v8::Function>::Cast(CcTest::global()
4349 ->Get(context.local(), v8_str("f")) 4554 ->Get(context.local(), v8_str("f"))
4350 .ToLocalChecked()))); 4555 .ToLocalChecked())));
4351 CHECK(f->is_compiled()); 4556 CHECK(f->is_compiled());
4352 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); 4557 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate));
4353 CompileRun("f = null"); 4558 CompileRun("f = null");
4354 } 4559 }
4355 4560
4356 // Lookup the optimized code and keep it alive. 4561 // Lookup the optimized code and keep it alive.
4357 Code* result = shared->SearchOptimizedCodeMap( 4562 CodeAndLiterals result = shared->SearchOptimizedCodeMap(
4358 isolate->context()->native_context(), BailoutId::None()); 4563 isolate->context()->native_context(), BailoutId::None());
4359 Handle<Code> optimized_code(result, isolate); 4564 Handle<Code> optimized_code(result.code, isolate);
4360 4565
4361 // Finish a full GC cycle so that the unoptimized code of 'g' is flushed even 4566 // Finish a full GC cycle so that the unoptimized code of 'g' is flushed even
4362 // though the optimized code for 'f' is reachable via the optimized code map. 4567 // though the optimized code for 'f' is reachable via the optimized code map.
4363 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); 4568 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
4364 4569
4365 // Make a new closure that will get code installed from the code map. 4570 // Make a new closure that will get code installed from the code map.
4366 // Unoptimized code is missing and the deoptimizer will go ballistic. 4571 // Unoptimized code is missing and the deoptimizer will go ballistic.
4367 CompileRun("var h = mkClosure(); h('bozo');"); 4572 CompileRun("var h = mkClosure(); h('bozo');");
4368 } 4573 }
4369 4574
(...skipping 2500 matching lines...) Expand 10 before | Expand all | Expand 10 after
6870 double deadline = heap->MonotonicallyIncreasingTimeInMs() + 1; 7075 double deadline = heap->MonotonicallyIncreasingTimeInMs() + 1;
6871 marking->AdvanceIncrementalMarking( 7076 marking->AdvanceIncrementalMarking(
6872 deadline, IncrementalMarking::GC_VIA_STACK_GUARD, 7077 deadline, IncrementalMarking::GC_VIA_STACK_GUARD,
6873 IncrementalMarking::FORCE_COMPLETION, StepOrigin::kV8); 7078 IncrementalMarking::FORCE_COMPLETION, StepOrigin::kV8);
6874 } 7079 }
6875 DCHECK(marking->IsStopped()); 7080 DCHECK(marking->IsStopped());
6876 } 7081 }
6877 7082
6878 } // namespace internal 7083 } // namespace internal
6879 } // namespace v8 7084 } // namespace v8
OLDNEW
« no previous file with comments | « src/type-feedback-vector.cc ('k') | test/cctest/test-feedback-vector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698