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

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

Issue 677043002: Flush code faster when doing emergency GCs. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Change ReleaseUnoptimizedCode test to a harder test that fails without this CL Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-api.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 3056 matching lines...) Expand 10 before | Expand all | Expand 10 after
3067 // where there are 2 pages left instead of 1, then we should increase the 3067 // where there are 2 pages left instead of 1, then we should increase the
3068 // size of the first page a little in SizeOfFirstPage in spaces.cc. The 3068 // size of the first page a little in SizeOfFirstPage in spaces.cc. The
3069 // first page should be small in order to reduce memory used when the VM 3069 // first page should be small in order to reduce memory used when the VM
3070 // boots, but if the 20 small arrays don't fit on the first page then that's 3070 // boots, but if the 20 small arrays don't fit on the first page then that's
3071 // an indication that it is too small. 3071 // an indication that it is too small.
3072 heap->CollectAllAvailableGarbage("triggered really hard"); 3072 heap->CollectAllAvailableGarbage("triggered really hard");
3073 CHECK_EQ(1, old_pointer_space->CountTotalPages()); 3073 CHECK_EQ(1, old_pointer_space->CountTotalPages());
3074 } 3074 }
3075 3075
3076 3076
3077 // Tests the FlushEagerly class from heap.h
3078 TEST(ReleaseUnoptimizedCode) {
3079 i::FLAG_trace_gc = true;
3080 // The optimizer can allocate stuff, messing up the test.
3081 i::FLAG_crankshaft = false;
3082 if (i::FLAG_always_opt) return;
3083
3084 CcTest::InitializeVM();
3085 Isolate* isolate = CcTest::i_isolate();
3086 Heap* heap = isolate->heap();
3087 v8::HandleScope scope(CcTest::isolate());
3088
3089 PagedSpace* code_space = heap->code_space();
3090 CompileRun(
3091 "var a = [];"
3092 "var sum = 0;"
3093 "for (var j = 0; j < 1e4; j++) {"
3094 " var fn = new Function("
3095 " 'var k; var o = {}; for (k in o) { } return ' + j + ';');"
3096 " sum += fn();"
3097 " a.push(fn);"
3098 "}");
3099 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation");
3100 CHECK_GE(code_space->CountTotalPages(), 5);
3101 // We trigger an emergency GC, but only one round, because that should be
3102 // enough to flush out the code.
3103 heap->CollectAllAvailableGarbage("triggered really hard", 2);
3104 CHECK_LE(code_space->CountTotalPages(), 2);
3105 }
3106
3107
3108 // Tests the FlushEagerly class from heap.h on regexp code.
3109 TEST(ReleaseRegexpCode) {
3110 i::FLAG_trace_gc = true;
3111 // The optimizer can allocate stuff, messing up the test.
3112 i::FLAG_crankshaft = false;
3113 if (i::FLAG_always_opt) return;
3114
3115 CcTest::InitializeVM();
3116 Isolate* isolate = CcTest::i_isolate();
3117 Heap* heap = isolate->heap();
3118 v8::HandleScope scope(CcTest::isolate());
3119
3120 PagedSpace* code_space = heap->code_space();
3121 CompileRun(
3122 "var a = [];"
3123 "for (var j = 0; j < 2e4; j++) {"
3124 " var re = RegExp(j + '?');"
3125 " a.push(re);"
3126 " re.test('foo');"
3127 "}");
3128 heap->CollectAllGarbage(Heap::kNoGCFlags, "triggered for preparation");
3129 CHECK_GT(code_space->CountTotalPages(), 5);
3130 // We trigger an emergency GC, but only one round, because that should be
3131 // enough to flush out the code.
3132 heap->CollectAllAvailableGarbage("triggered really hard", 1);
3133 CHECK_LE(code_space->CountTotalPages(), 2);
3134 }
3135
3136
3077 TEST(Regress2237) { 3137 TEST(Regress2237) {
3078 i::FLAG_stress_compaction = false; 3138 i::FLAG_stress_compaction = false;
3079 CcTest::InitializeVM(); 3139 CcTest::InitializeVM();
3080 Isolate* isolate = CcTest::i_isolate(); 3140 Isolate* isolate = CcTest::i_isolate();
3081 Factory* factory = isolate->factory(); 3141 Factory* factory = isolate->factory();
3082 v8::HandleScope scope(CcTest::isolate()); 3142 v8::HandleScope scope(CcTest::isolate());
3083 Handle<String> slice(CcTest::heap()->empty_string()); 3143 Handle<String> slice(CcTest::heap()->empty_string());
3084 3144
3085 { 3145 {
3086 // Generate a parent that lives in new-space. 3146 // Generate a parent that lives in new-space.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3359 v8::Handle<v8::String> source_string = 3419 v8::Handle<v8::String> source_string =
3360 v8::String::NewExternal(isolate, resource); 3420 v8::String::NewExternal(isolate, resource);
3361 i_isolate->heap()->CollectAllAvailableGarbage(); 3421 i_isolate->heap()->CollectAllAvailableGarbage();
3362 v8::Script::Compile(source_string)->Run(); 3422 v8::Script::Compile(source_string)->Run();
3363 CHECK(!resource->IsDisposed()); 3423 CHECK(!resource->IsDisposed());
3364 } 3424 }
3365 // i_isolate->heap()->CollectAllAvailableGarbage(); 3425 // i_isolate->heap()->CollectAllAvailableGarbage();
3366 CHECK(!resource->IsDisposed()); 3426 CHECK(!resource->IsDisposed());
3367 3427
3368 CompileRun(accessor); 3428 CompileRun(accessor);
3369 i_isolate->heap()->CollectAllAvailableGarbage(); 3429 i_isolate->heap()->CollectAllAvailableGarbage(
3430 "force release of external source in one round", 1);
3370 3431
3371 // External source has been released. 3432 // External source has been released.
3372 CHECK(resource->IsDisposed()); 3433 CHECK(resource->IsDisposed());
3373 delete resource; 3434 delete resource;
3374 } 3435 }
3375 3436
3376 3437
3377 UNINITIALIZED_TEST(ReleaseStackTraceData) { 3438 UNINITIALIZED_TEST(ReleaseStackTraceData) {
3378 if (i::FLAG_always_opt) { 3439 if (i::FLAG_always_opt) {
3379 // TODO(ulan): Remove this once the memory leak via code_next_link is fixed. 3440 // TODO(ulan): Remove this once the memory leak via code_next_link is fixed.
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
4119 { 4180 {
4120 HandleScope scope(heap->isolate()); 4181 HandleScope scope(heap->isolate());
4121 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal"); 4182 Handle<JSFunction> mortal = OptimizeDummyFunction("mortal");
4122 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal"); 4183 Handle<JSFunction> immortal = OptimizeDummyFunction("immortal");
4123 CHECK_EQ(immortal->code()->next_code_link(), mortal->code()); 4184 CHECK_EQ(immortal->code()->next_code_link(), mortal->code());
4124 code_chain_length_before = GetCodeChainLength(immortal->code()); 4185 code_chain_length_before = GetCodeChainLength(immortal->code());
4125 // Keep the immortal code and let the mortal code die. 4186 // Keep the immortal code and let the mortal code die.
4126 code = scope.CloseAndEscape(Handle<Code>(immortal->code())); 4187 code = scope.CloseAndEscape(Handle<Code>(immortal->code()));
4127 CompileRun("mortal = null; immortal = null;"); 4188 CompileRun("mortal = null; immortal = null;");
4128 } 4189 }
4129 heap->CollectAllAvailableGarbage(); 4190 heap->CollectAllAvailableGarbage("kill mortal code", 1);
4130 // Now mortal code should be dead. 4191 // Now mortal code should be dead.
4131 code_chain_length_after = GetCodeChainLength(*code); 4192 code_chain_length_after = GetCodeChainLength(*code);
4132 CHECK_EQ(code_chain_length_before - 1, code_chain_length_after); 4193 CHECK_EQ(code_chain_length_before - 1, code_chain_length_after);
4133 } 4194 }
4134 4195
4135 4196
4136 static Handle<Code> DummyOptimizedCode(Isolate* isolate) { 4197 static Handle<Code> DummyOptimizedCode(Isolate* isolate) {
4137 i::byte buffer[i::Assembler::kMinimalBufferSize]; 4198 i::byte buffer[i::Assembler::kMinimalBufferSize];
4138 MacroAssembler masm(isolate, buffer, sizeof(buffer)); 4199 MacroAssembler masm(isolate, buffer, sizeof(buffer));
4139 CodeDesc desc; 4200 CodeDesc desc;
(...skipping 22 matching lines...) Expand all
4162 Handle<Object> old_head(context->get(Context::OPTIMIZED_CODE_LIST), isolate); 4223 Handle<Object> old_head(context->get(Context::OPTIMIZED_CODE_LIST), isolate);
4163 { 4224 {
4164 HandleScope scope(heap->isolate()); 4225 HandleScope scope(heap->isolate());
4165 Handle<Code> immortal = DummyOptimizedCode(isolate); 4226 Handle<Code> immortal = DummyOptimizedCode(isolate);
4166 Handle<Code> mortal = DummyOptimizedCode(isolate); 4227 Handle<Code> mortal = DummyOptimizedCode(isolate);
4167 mortal->set_next_code_link(*old_head); 4228 mortal->set_next_code_link(*old_head);
4168 immortal->set_next_code_link(*mortal); 4229 immortal->set_next_code_link(*mortal);
4169 context->set(Context::OPTIMIZED_CODE_LIST, *immortal); 4230 context->set(Context::OPTIMIZED_CODE_LIST, *immortal);
4170 new_head = scope.CloseAndEscape(immortal); 4231 new_head = scope.CloseAndEscape(immortal);
4171 } 4232 }
4172 heap->CollectAllAvailableGarbage(); 4233 heap->CollectAllAvailableGarbage("kill mortal code", 1);
4173 // Now mortal code should be dead. 4234 // Now mortal code should be dead.
4174 CHECK_EQ(*old_head, new_head->next_code_link()); 4235 CHECK_EQ(*old_head, new_head->next_code_link());
4175 } 4236 }
4176 4237
4177 4238
4178 static bool weak_ic_cleared = false; 4239 static bool weak_ic_cleared = false;
4179 4240
4180 static void ClearWeakIC(const v8::WeakCallbackData<v8::Object, void>& data) { 4241 static void ClearWeakIC(const v8::WeakCallbackData<v8::Object, void>& data) {
4181 printf("clear weak is called\n"); 4242 printf("clear weak is called\n");
4182 weak_ic_cleared = true; 4243 weak_ic_cleared = true;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
4304 weak_cell2 = inner_scope.CloseAndEscape(factory->NewWeakCell(survivor)); 4365 weak_cell2 = inner_scope.CloseAndEscape(factory->NewWeakCell(survivor));
4305 } 4366 }
4306 CHECK(weak_cell1->value()->IsFixedArray()); 4367 CHECK(weak_cell1->value()->IsFixedArray());
4307 CHECK_EQ(*survivor, weak_cell2->value()); 4368 CHECK_EQ(*survivor, weak_cell2->value());
4308 heap->CollectGarbage(NEW_SPACE); 4369 heap->CollectGarbage(NEW_SPACE);
4309 CHECK(weak_cell1->value()->IsFixedArray()); 4370 CHECK(weak_cell1->value()->IsFixedArray());
4310 CHECK_EQ(*survivor, weak_cell2->value()); 4371 CHECK_EQ(*survivor, weak_cell2->value());
4311 heap->CollectGarbage(NEW_SPACE); 4372 heap->CollectGarbage(NEW_SPACE);
4312 CHECK(weak_cell1->value()->IsFixedArray()); 4373 CHECK(weak_cell1->value()->IsFixedArray());
4313 CHECK_EQ(*survivor, weak_cell2->value()); 4374 CHECK_EQ(*survivor, weak_cell2->value());
4314 heap->CollectAllAvailableGarbage(); 4375 heap->CollectAllAvailableGarbage("kill weak cell", 1);
4315 CHECK(weak_cell1->cleared()); 4376 CHECK(weak_cell1->cleared());
4316 CHECK_EQ(*survivor, weak_cell2->value()); 4377 CHECK_EQ(*survivor, weak_cell2->value());
4317 } 4378 }
4318 4379
4319 4380
4320 TEST(WeakCellsWithIncrementalMarking) { 4381 TEST(WeakCellsWithIncrementalMarking) {
4321 CcTest::InitializeVM(); 4382 CcTest::InitializeVM();
4322 Isolate* isolate = CcTest::i_isolate(); 4383 Isolate* isolate = CcTest::i_isolate();
4323 v8::internal::Heap* heap = CcTest::heap(); 4384 v8::internal::Heap* heap = CcTest::heap();
4324 v8::internal::Factory* factory = isolate->factory(); 4385 v8::internal::Factory* factory = isolate->factory();
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
4613 #ifdef DEBUG 4674 #ifdef DEBUG
4614 TEST(PathTracer) { 4675 TEST(PathTracer) {
4615 CcTest::InitializeVM(); 4676 CcTest::InitializeVM();
4616 v8::HandleScope scope(CcTest::isolate()); 4677 v8::HandleScope scope(CcTest::isolate());
4617 4678
4618 v8::Local<v8::Value> result = CompileRun("'abc'"); 4679 v8::Local<v8::Value> result = CompileRun("'abc'");
4619 Handle<Object> o = v8::Utils::OpenHandle(*result); 4680 Handle<Object> o = v8::Utils::OpenHandle(*result);
4620 CcTest::i_isolate()->heap()->TracePathToObject(*o); 4681 CcTest::i_isolate()->heap()->TracePathToObject(*o);
4621 } 4682 }
4622 #endif // DEBUG 4683 #endif // DEBUG
OLDNEW
« no previous file with comments | « test/cctest/test-api.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698