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

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

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

Powered by Google App Engine
This is Rietveld 408576698