| OLD | NEW |
| 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 4281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 = | 4300 Handle<TypeFeedbackVector> vector = |
| 4301 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); | 4301 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); |
| 4302 Handle<LiteralsArray> lit = | |
| 4303 LiteralsArray::New(isolate, vector, shared->num_literals()); | |
| 4304 Handle<Context> context(isolate->context()); | 4302 Handle<Context> context(isolate->context()); |
| 4305 | 4303 |
| 4306 // Add the new code several times to the optimized code map and also set an | 4304 // Add the new code several times to the optimized code map and also set an |
| 4307 // allocation timeout so that expanding the code map will trigger a GC. | 4305 // allocation timeout so that expanding the code map will trigger a GC. |
| 4308 heap->set_allocation_timeout(5); | 4306 heap->set_allocation_timeout(5); |
| 4309 FLAG_gc_interval = 1000; | 4307 FLAG_gc_interval = 1000; |
| 4310 for (int i = 0; i < 10; ++i) { | 4308 for (int i = 0; i < 10; ++i) { |
| 4311 BailoutId id = BailoutId(i); | 4309 BailoutId id = BailoutId(i); |
| 4312 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); | 4310 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, vector, |
| 4311 id); |
| 4313 } | 4312 } |
| 4314 } | 4313 } |
| 4315 #endif // DEBUG | 4314 #endif // DEBUG |
| 4316 | 4315 |
| 4317 TEST(Regress514122) { | 4316 TEST(Regress514122) { |
| 4318 if (!i::FLAG_incremental_marking) return; | 4317 if (!i::FLAG_incremental_marking) return; |
| 4319 i::FLAG_allow_natives_syntax = true; | 4318 i::FLAG_allow_natives_syntax = true; |
| 4320 CcTest::InitializeVM(); | 4319 CcTest::InitializeVM(); |
| 4321 Isolate* isolate = CcTest::i_isolate(); | 4320 Isolate* isolate = CcTest::i_isolate(); |
| 4322 LocalContext env; | 4321 LocalContext env; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4351 | 4350 |
| 4352 Handle<JSFunction> g = Handle<JSFunction>::cast( | 4351 Handle<JSFunction> g = Handle<JSFunction>::cast( |
| 4353 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 4352 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 4354 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); | 4353 CcTest::global()->Get(env.local(), v8_str("g")).ToLocalChecked()))); |
| 4355 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); | 4354 code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); |
| 4356 if (!code->is_optimized_code()) return; | 4355 if (!code->is_optimized_code()) return; |
| 4357 } | 4356 } |
| 4358 | 4357 |
| 4359 Handle<TypeFeedbackVector> vector = | 4358 Handle<TypeFeedbackVector> vector = |
| 4360 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); | 4359 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()); | 4360 Handle<Context> context(isolate->context()); |
| 4364 | 4361 |
| 4365 // Add the code several times to the optimized code map. | 4362 // Add the code several times to the optimized code map. |
| 4366 for (int i = 0; i < 3; ++i) { | 4363 for (int i = 0; i < 3; ++i) { |
| 4367 HandleScope inner_scope(isolate); | 4364 HandleScope inner_scope(isolate); |
| 4368 BailoutId id = BailoutId(i); | 4365 BailoutId id = BailoutId(i); |
| 4369 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); | 4366 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, vector, |
| 4367 id); |
| 4370 } | 4368 } |
| 4371 shared->optimized_code_map()->Print(); | 4369 shared->optimized_code_map()->Print(); |
| 4372 | 4370 |
| 4373 // Add the code with a literals array to be evacuated. | 4371 // Add the code with a feedback vector to be evacuated. |
| 4374 Page* evac_page; | 4372 Page* evac_page; |
| 4375 { | 4373 { |
| 4376 HandleScope inner_scope(isolate); | 4374 HandleScope inner_scope(isolate); |
| 4377 AlwaysAllocateScope always_allocate(isolate); | 4375 AlwaysAllocateScope always_allocate(isolate); |
| 4378 // Make sure literal is placed on an old-space evacuation candidate. | 4376 // Make sure literal is placed on an old-space evacuation candidate. |
| 4379 heap::SimulateFullSpace(heap->old_space()); | 4377 heap::SimulateFullSpace(heap->old_space()); |
| 4380 | 4378 |
| 4381 // Make sure there the number of literals is > 0. | 4379 // Make sure there the number of literals is > 0. |
| 4382 Handle<LiteralsArray> lit = LiteralsArray::New(isolate, vector, 23); | 4380 Handle<TypeFeedbackVector> vector = |
| 4383 | 4381 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); |
| 4384 evac_page = Page::FromAddress(lit->address()); | 4382 evac_page = Page::FromAddress(vector->address()); |
| 4385 BailoutId id = BailoutId(100); | 4383 BailoutId id = BailoutId(100); |
| 4386 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); | 4384 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, vector, |
| 4385 id); |
| 4387 } | 4386 } |
| 4388 | 4387 |
| 4389 // Heap is ready, force {lit_page} to become an evacuation candidate and | 4388 // Heap is ready, force {lit_page} to become an evacuation candidate and |
| 4390 // simulate incremental marking to enqueue optimized code map. | 4389 // simulate incremental marking to enqueue optimized code map. |
| 4391 FLAG_manual_evacuation_candidates_selection = true; | 4390 FLAG_manual_evacuation_candidates_selection = true; |
| 4392 heap::ForceEvacuationCandidate(evac_page); | 4391 heap::ForceEvacuationCandidate(evac_page); |
| 4393 heap::SimulateIncrementalMarking(heap); | 4392 heap::SimulateIncrementalMarking(heap); |
| 4394 | 4393 |
| 4395 // No matter whether reachable or not, {boomer} is doomed. | 4394 // No matter whether reachable or not, {boomer} is doomed. |
| 4396 Handle<Object> boomer(shared->optimized_code_map(), isolate); | 4395 Handle<Object> boomer(shared->optimized_code_map(), isolate); |
| 4397 | 4396 |
| 4398 // Add the code several times to the optimized code map. This will leave old | 4397 // 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. | 4398 // copies of the optimized code map unreachable but still marked. |
| 4400 for (int i = 3; i < 6; ++i) { | 4399 for (int i = 3; i < 6; ++i) { |
| 4401 HandleScope inner_scope(isolate); | 4400 HandleScope inner_scope(isolate); |
| 4402 BailoutId id = BailoutId(i); | 4401 BailoutId id = BailoutId(i); |
| 4403 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); | 4402 SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, vector, |
| 4403 id); |
| 4404 } | 4404 } |
| 4405 | 4405 |
| 4406 // Trigger a GC to flush out the bug. | 4406 // Trigger a GC to flush out the bug. |
| 4407 CcTest::CollectGarbage(i::OLD_SPACE); | 4407 CcTest::CollectGarbage(i::OLD_SPACE); |
| 4408 boomer->Print(); | 4408 boomer->Print(); |
| 4409 } | 4409 } |
| 4410 | 4410 |
| 4411 TEST(OptimizedCodeMapReuseEntries) { | 4411 TEST(OptimizedCodeMapReuseEntries) { |
| 4412 i::FLAG_allow_natives_syntax = true; | 4412 i::FLAG_allow_natives_syntax = true; |
| 4413 // BUG(v8:4598): Since TurboFan doesn't treat maps in code weakly, we can't | 4413 // BUG(v8:4598): Since TurboFan doesn't treat maps in code weakly, we can't |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4552 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 4552 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 4553 *v8::Local<v8::Function>::Cast(CcTest::global() | 4553 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 4554 ->Get(context.local(), v8_str("f")) | 4554 ->Get(context.local(), v8_str("f")) |
| 4555 .ToLocalChecked()))); | 4555 .ToLocalChecked()))); |
| 4556 CHECK(f->is_compiled()); | 4556 CHECK(f->is_compiled()); |
| 4557 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); | 4557 shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); |
| 4558 CompileRun("f = null"); | 4558 CompileRun("f = null"); |
| 4559 } | 4559 } |
| 4560 | 4560 |
| 4561 // Lookup the optimized code and keep it alive. | 4561 // Lookup the optimized code and keep it alive. |
| 4562 CodeAndLiterals result = shared->SearchOptimizedCodeMap( | 4562 CodeAndVector result = shared->SearchOptimizedCodeMap( |
| 4563 isolate->context()->native_context(), BailoutId::None()); | 4563 isolate->context()->native_context(), BailoutId::None()); |
| 4564 Handle<Code> optimized_code(result.code, isolate); | 4564 Handle<Code> optimized_code(result.code, isolate); |
| 4565 | 4565 |
| 4566 // 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 |
| 4567 // 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. |
| 4568 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); | 4568 CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask); |
| 4569 | 4569 |
| 4570 // 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. |
| 4571 // Unoptimized code is missing and the deoptimizer will go ballistic. | 4571 // Unoptimized code is missing and the deoptimizer will go ballistic. |
| 4572 CompileRun("var h = mkClosure(); h('bozo');"); | 4572 CompileRun("var h = mkClosure(); h('bozo');"); |
| (...skipping 2517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7090 CHECK(!heap->code_space()->FirstPage()->Contains(code->address())); | 7090 CHECK(!heap->code_space()->FirstPage()->Contains(code->address())); |
| 7091 | 7091 |
| 7092 // Ensure it's not in large object space. | 7092 // Ensure it's not in large object space. |
| 7093 MemoryChunk* chunk = MemoryChunk::FromAddress(code->address()); | 7093 MemoryChunk* chunk = MemoryChunk::FromAddress(code->address()); |
| 7094 CHECK(chunk->owner()->identity() != LO_SPACE); | 7094 CHECK(chunk->owner()->identity() != LO_SPACE); |
| 7095 CHECK(chunk->NeverEvacuate()); | 7095 CHECK(chunk->NeverEvacuate()); |
| 7096 } | 7096 } |
| 7097 | 7097 |
| 7098 } // namespace internal | 7098 } // namespace internal |
| 7099 } // namespace v8 | 7099 } // namespace v8 |
| OLD | NEW |