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

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

Powered by Google App Engine
This is Rietveld 408576698