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 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1045 Object* clone_obj = heap->CopyJSObject(jsobject).ToObjectChecked(); | 1045 Object* clone_obj = heap->CopyJSObject(jsobject).ToObjectChecked(); |
1046 JSObject* clone = JSObject::cast(clone_obj); | 1046 JSObject* clone = JSObject::cast(clone_obj); |
1047 if (clone->address() != old_pointer_space_top) { | 1047 if (clone->address() != old_pointer_space_top) { |
1048 // Alas, got allocated from free list, we cannot do checks. | 1048 // Alas, got allocated from free list, we cannot do checks. |
1049 return; | 1049 return; |
1050 } | 1050 } |
1051 CHECK(heap->old_pointer_space()->Contains(clone->address())); | 1051 CHECK(heap->old_pointer_space()->Contains(clone->address())); |
1052 } | 1052 } |
1053 | 1053 |
1054 | 1054 |
1055 UNINITIALIZED_TEST(TestCodeFlushing) { | 1055 TEST(TestCodeFlushing) { |
1056 // If we do not flush code this test is invalid. | 1056 // If we do not flush code this test is invalid. |
1057 if (!FLAG_flush_code) return; | 1057 if (!FLAG_flush_code) return; |
1058 i::FLAG_allow_natives_syntax = true; | 1058 i::FLAG_allow_natives_syntax = true; |
1059 i::FLAG_optimize_for_size = false; | 1059 i::FLAG_optimize_for_size = false; |
1060 v8::Isolate* isolate = v8::Isolate::New(); | 1060 CcTest::InitializeVM(); |
1061 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 1061 Isolate* isolate = CcTest::i_isolate(); |
1062 isolate->Enter(); | 1062 Factory* factory = isolate->factory(); |
1063 Factory* factory = i_isolate->factory(); | 1063 v8::HandleScope scope(CcTest::isolate()); |
1064 { | 1064 const char* source = "function foo() {" |
1065 v8::HandleScope scope(isolate); | 1065 " var x = 42;" |
1066 v8::Context::New(isolate)->Enter(); | 1066 " var y = 42;" |
1067 const char* source = | 1067 " var z = x + y;" |
1068 "function foo() {" | 1068 "};" |
1069 " var x = 42;" | 1069 "foo()"; |
1070 " var y = 42;" | 1070 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); |
1071 " var z = x + y;" | |
1072 "};" | |
1073 "foo()"; | |
1074 Handle<String> foo_name = factory->InternalizeUtf8String("foo"); | |
1075 | 1071 |
1076 // This compile will add the code to the compilation cache. | 1072 // This compile will add the code to the compilation cache. |
1077 { | 1073 { v8::HandleScope scope(CcTest::isolate()); |
1078 v8::HandleScope scope(isolate); | 1074 CompileRun(source); |
1079 CompileRun(source); | 1075 } |
1080 } | |
1081 | 1076 |
1082 // Check function is compiled. | 1077 // Check function is compiled. |
1083 Handle<Object> func_value = Object::GetProperty(i_isolate->global_object(), | 1078 Handle<Object> func_value = Object::GetProperty( |
1084 foo_name).ToHandleChecked(); | 1079 CcTest::i_isolate()->global_object(), foo_name).ToHandleChecked(); |
1085 CHECK(func_value->IsJSFunction()); | 1080 CHECK(func_value->IsJSFunction()); |
1086 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); | 1081 Handle<JSFunction> function = Handle<JSFunction>::cast(func_value); |
1087 CHECK(function->shared()->is_compiled()); | 1082 CHECK(function->shared()->is_compiled()); |
1088 | 1083 |
1089 // The code will survive at least two GCs. | 1084 // The code will survive at least two GCs. |
1090 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1085 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
1091 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1086 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
1092 CHECK(function->shared()->is_compiled()); | 1087 CHECK(function->shared()->is_compiled()); |
1093 | 1088 |
1094 // Simulate several GCs that use full marking. | 1089 // Simulate several GCs that use full marking. |
1095 const int kAgingThreshold = 6; | 1090 const int kAgingThreshold = 6; |
1096 for (int i = 0; i < kAgingThreshold; i++) { | 1091 for (int i = 0; i < kAgingThreshold; i++) { |
1097 i_isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 1092 CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
1098 } | 1093 } |
1099 | 1094 |
1100 // foo should no longer be in the compilation cache | 1095 // foo should no longer be in the compilation cache |
1101 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); | 1096 CHECK(!function->shared()->is_compiled() || function->IsOptimized()); |
1102 CHECK(!function->is_compiled() || function->IsOptimized()); | 1097 CHECK(!function->is_compiled() || function->IsOptimized()); |
1103 // Call foo to get it recompiled. | 1098 // Call foo to get it recompiled. |
1104 CompileRun("foo()"); | 1099 CompileRun("foo()"); |
1105 CHECK(function->shared()->is_compiled()); | 1100 CHECK(function->shared()->is_compiled()); |
1106 CHECK(function->is_compiled()); | 1101 CHECK(function->is_compiled()); |
1107 } | |
1108 isolate->Exit(); | |
1109 isolate->Dispose(); | |
1110 } | 1102 } |
1111 | 1103 |
1112 | 1104 |
1113 TEST(TestCodeFlushingPreAged) { | 1105 TEST(TestCodeFlushingPreAged) { |
1114 // If we do not flush code this test is invalid. | 1106 // If we do not flush code this test is invalid. |
1115 if (!FLAG_flush_code) return; | 1107 if (!FLAG_flush_code) return; |
1116 i::FLAG_allow_natives_syntax = true; | 1108 i::FLAG_allow_natives_syntax = true; |
1117 i::FLAG_optimize_for_size = true; | 1109 i::FLAG_optimize_for_size = true; |
1118 CcTest::InitializeVM(); | 1110 CcTest::InitializeVM(); |
1119 Isolate* isolate = CcTest::i_isolate(); | 1111 Isolate* isolate = CcTest::i_isolate(); |
(...skipping 2178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 size_t length() const { return length_; } | 3290 size_t length() const { return length_; } |
3299 | 3291 |
3300 bool IsDisposed() { return data_ == NULL; } | 3292 bool IsDisposed() { return data_ == NULL; } |
3301 | 3293 |
3302 private: | 3294 private: |
3303 const char* data_; | 3295 const char* data_; |
3304 size_t length_; | 3296 size_t length_; |
3305 }; | 3297 }; |
3306 | 3298 |
3307 | 3299 |
3308 void ReleaseStackTraceDataTest(v8::Isolate* isolate, const char* source, | 3300 void ReleaseStackTraceDataTest(const char* source, const char* accessor) { |
3309 const char* accessor) { | |
3310 // Test that the data retained by the Error.stack accessor is released | 3301 // Test that the data retained by the Error.stack accessor is released |
3311 // after the first time the accessor is fired. We use external string | 3302 // after the first time the accessor is fired. We use external string |
3312 // to check whether the data is being released since the external string | 3303 // to check whether the data is being released since the external string |
3313 // resource's callback is fired when the external string is GC'ed. | 3304 // resource's callback is fired when the external string is GC'ed. |
3314 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 3305 v8::HandleScope scope(CcTest::isolate()); |
3315 v8::HandleScope scope(isolate); | |
3316 SourceResource* resource = new SourceResource(i::StrDup(source)); | 3306 SourceResource* resource = new SourceResource(i::StrDup(source)); |
3317 { | 3307 { |
3318 v8::HandleScope scope(isolate); | 3308 v8::HandleScope scope(CcTest::isolate()); |
3319 v8::Handle<v8::String> source_string = | 3309 v8::Handle<v8::String> source_string = |
3320 v8::String::NewExternal(isolate, resource); | 3310 v8::String::NewExternal(CcTest::isolate(), resource); |
3321 i_isolate->heap()->CollectAllAvailableGarbage(); | 3311 CcTest::heap()->CollectAllAvailableGarbage(); |
3322 v8::Script::Compile(source_string)->Run(); | 3312 v8::Script::Compile(source_string)->Run(); |
3323 CHECK(!resource->IsDisposed()); | 3313 CHECK(!resource->IsDisposed()); |
3324 } | 3314 } |
3325 // i_isolate->heap()->CollectAllAvailableGarbage(); | 3315 // CcTest::heap()->CollectAllAvailableGarbage(); |
3326 CHECK(!resource->IsDisposed()); | 3316 CHECK(!resource->IsDisposed()); |
3327 | 3317 |
3328 CompileRun(accessor); | 3318 CompileRun(accessor); |
3329 i_isolate->heap()->CollectAllAvailableGarbage(); | 3319 CcTest::heap()->CollectAllAvailableGarbage(); |
3330 | 3320 |
3331 // External source has been released. | 3321 // External source has been released. |
3332 CHECK(resource->IsDisposed()); | 3322 CHECK(resource->IsDisposed()); |
3333 delete resource; | 3323 delete resource; |
3334 } | 3324 } |
3335 | 3325 |
3336 | 3326 |
3337 UNINITIALIZED_TEST(ReleaseStackTraceData) { | 3327 TEST(ReleaseStackTraceData) { |
3338 if (i::FLAG_always_opt) { | 3328 if (i::FLAG_always_opt) { |
3339 // TODO(ulan): Remove this once the memory leak via code_next_link is fixed. | 3329 // TODO(ulan): Remove this once the memory leak via code_next_link is fixed. |
3340 // See: https://codereview.chromium.org/181833004/ | 3330 // See: https://codereview.chromium.org/181833004/ |
3341 return; | 3331 return; |
3342 } | 3332 } |
3343 FLAG_use_ic = false; // ICs retain objects. | 3333 FLAG_use_ic = false; // ICs retain objects. |
3344 FLAG_concurrent_recompilation = false; | 3334 FLAG_concurrent_recompilation = false; |
3345 v8::Isolate* isolate = v8::Isolate::New(); | 3335 CcTest::InitializeVM(); |
3346 { | 3336 static const char* source1 = "var error = null; " |
3347 v8::Isolate::Scope isolate_scope(isolate); | 3337 /* Normal Error */ "try { " |
3348 v8::HandleScope handle_scope(isolate); | 3338 " throw new Error(); " |
3349 v8::Context::New(isolate)->Enter(); | 3339 "} catch (e) { " |
3350 static const char* source1 = "var error = null; " | 3340 " error = e; " |
3351 /* Normal Error */ "try { " | 3341 "} "; |
3352 " throw new Error(); " | 3342 static const char* source2 = "var error = null; " |
3353 "} catch (e) { " | 3343 /* Stack overflow */ "try { " |
3354 " error = e; " | 3344 " (function f() { f(); })(); " |
3355 "} "; | 3345 "} catch (e) { " |
3356 static const char* source2 = "var error = null; " | 3346 " error = e; " |
3357 /* Stack overflow */ "try { " | 3347 "} "; |
3358 " (function f() { f(); })(); " | 3348 static const char* source3 = "var error = null; " |
3359 "} catch (e) { " | 3349 /* Normal Error */ "try { " |
3360 " error = e; " | 3350 /* as prototype */ " throw new Error(); " |
3361 "} "; | 3351 "} catch (e) { " |
3362 static const char* source3 = "var error = null; " | 3352 " error = {}; " |
3363 /* Normal Error */ "try { " | 3353 " error.__proto__ = e; " |
3364 /* as prototype */ " throw new Error(); " | 3354 "} "; |
3365 "} catch (e) { " | 3355 static const char* source4 = "var error = null; " |
3366 " error = {}; " | 3356 /* Stack overflow */ "try { " |
3367 " error.__proto__ = e; " | 3357 /* as prototype */ " (function f() { f(); })(); " |
3368 "} "; | 3358 "} catch (e) { " |
3369 static const char* source4 = "var error = null; " | 3359 " error = {}; " |
3370 /* Stack overflow */ "try { " | 3360 " error.__proto__ = e; " |
3371 /* as prototype */ " (function f() { f(); })(); " | 3361 "} "; |
3372 "} catch (e) { " | 3362 static const char* getter = "error.stack"; |
3373 " error = {}; " | 3363 static const char* setter = "error.stack = 0"; |
3374 " error.__proto__ = e; " | |
3375 "} "; | |
3376 static const char* getter = "error.stack"; | |
3377 static const char* setter = "error.stack = 0"; | |
3378 | 3364 |
3379 ReleaseStackTraceDataTest(isolate, source1, setter); | 3365 ReleaseStackTraceDataTest(source1, setter); |
3380 ReleaseStackTraceDataTest(isolate, source2, setter); | 3366 ReleaseStackTraceDataTest(source2, setter); |
3381 // We do not test source3 and source4 with setter, since the setter is | 3367 // We do not test source3 and source4 with setter, since the setter is |
3382 // supposed to (untypically) write to the receiver, not the holder. This is | 3368 // supposed to (untypically) write to the receiver, not the holder. This is |
3383 // to emulate the behavior of a data property. | 3369 // to emulate the behavior of a data property. |
3384 | 3370 |
3385 ReleaseStackTraceDataTest(isolate, source1, getter); | 3371 ReleaseStackTraceDataTest(source1, getter); |
3386 ReleaseStackTraceDataTest(isolate, source2, getter); | 3372 ReleaseStackTraceDataTest(source2, getter); |
3387 ReleaseStackTraceDataTest(isolate, source3, getter); | 3373 ReleaseStackTraceDataTest(source3, getter); |
3388 ReleaseStackTraceDataTest(isolate, source4, getter); | 3374 ReleaseStackTraceDataTest(source4, getter); |
3389 } | |
3390 } | 3375 } |
3391 | 3376 |
3392 | 3377 |
3393 TEST(Regress159140) { | 3378 TEST(Regress159140) { |
3394 i::FLAG_allow_natives_syntax = true; | 3379 i::FLAG_allow_natives_syntax = true; |
3395 i::FLAG_flush_code_incrementally = true; | 3380 i::FLAG_flush_code_incrementally = true; |
3396 CcTest::InitializeVM(); | 3381 CcTest::InitializeVM(); |
3397 Isolate* isolate = CcTest::i_isolate(); | 3382 Isolate* isolate = CcTest::i_isolate(); |
3398 Heap* heap = isolate->heap(); | 3383 Heap* heap = isolate->heap(); |
3399 HandleScope scope(isolate); | 3384 HandleScope scope(isolate); |
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4357 Handle<JSObject> o = | 4342 Handle<JSObject> o = |
4358 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); | 4343 v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result)); |
4359 CHECK(heap->InOldPointerSpace(o->elements())); | 4344 CHECK(heap->InOldPointerSpace(o->elements())); |
4360 CHECK(heap->InOldPointerSpace(*o)); | 4345 CHECK(heap->InOldPointerSpace(*o)); |
4361 Page* page = Page::FromAddress(o->elements()->address()); | 4346 Page* page = Page::FromAddress(o->elements()->address()); |
4362 CHECK(page->parallel_sweeping() <= MemoryChunk::SWEEPING_FINALIZE || | 4347 CHECK(page->parallel_sweeping() <= MemoryChunk::SWEEPING_FINALIZE || |
4363 Marking::IsBlack(Marking::MarkBitFrom(o->elements()))); | 4348 Marking::IsBlack(Marking::MarkBitFrom(o->elements()))); |
4364 } | 4349 } |
4365 | 4350 |
4366 | 4351 |
4367 UNINITIALIZED_TEST(PromotionQueue) { | 4352 TEST(PromotionQueue) { |
4368 i::FLAG_expose_gc = true; | 4353 i::FLAG_expose_gc = true; |
4369 i::FLAG_max_semi_space_size = 2; | 4354 i::FLAG_max_semi_space_size = 2; |
4370 v8::Isolate* isolate = v8::Isolate::New(); | 4355 CcTest::InitializeVM(); |
4371 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 4356 v8::HandleScope scope(CcTest::isolate()); |
4372 { | 4357 Isolate* isolate = CcTest::i_isolate(); |
4373 v8::Isolate::Scope isolate_scope(isolate); | 4358 Heap* heap = isolate->heap(); |
4374 v8::HandleScope handle_scope(isolate); | 4359 NewSpace* new_space = heap->new_space(); |
4375 v8::Context::New(isolate)->Enter(); | |
4376 Heap* heap = i_isolate->heap(); | |
4377 NewSpace* new_space = heap->new_space(); | |
4378 | 4360 |
4379 // In this test we will try to overwrite the promotion queue which is at the | 4361 // In this test we will try to overwrite the promotion queue which is at the |
4380 // end of to-space. To actually make that possible, we need at least two | 4362 // end of to-space. To actually make that possible, we need at least two |
4381 // semi-space pages and take advantage of fragementation. | 4363 // semi-space pages and take advantage of fragementation. |
4382 // (1) Grow semi-space to two pages. | 4364 // (1) Grow semi-space to two pages. |
4383 // (2) Create a few small long living objects and call the scavenger to | 4365 // (2) Create a few small long living objects and call the scavenger to |
4384 // move them to the other semi-space. | 4366 // move them to the other semi-space. |
4385 // (3) Create a huge object, i.e., remainder of first semi-space page and | 4367 // (3) Create a huge object, i.e., remainder of first semi-space page and |
4386 // create another huge object which should be of maximum allocatable memory | 4368 // create another huge object which should be of maximum allocatable memory |
4387 // size of the second semi-space page. | 4369 // size of the second semi-space page. |
4388 // (4) Call the scavenger again. | 4370 // (4) Call the scavenger again. |
4389 // What will happen is: the scavenger will promote the objects created in | 4371 // What will happen is: the scavenger will promote the objects created in (2) |
4390 // (2) and will create promotion queue entries at the end of the second | 4372 // and will create promotion queue entries at the end of the second |
4391 // semi-space page during the next scavenge when it promotes the objects to | 4373 // semi-space page during the next scavenge when it promotes the objects to |
4392 // the old generation. The first allocation of (3) will fill up the first | 4374 // the old generation. The first allocation of (3) will fill up the first |
4393 // semi-space page. The second allocation in (3) will not fit into the | 4375 // semi-space page. The second allocation in (3) will not fit into the first |
4394 // first semi-space page, but it will overwrite the promotion queue which | 4376 // semi-space page, but it will overwrite the promotion queue which are in |
4395 // are in the second semi-space page. If the right guards are in place, the | 4377 // the second semi-space page. If the right guards are in place, the promotion |
4396 // promotion queue will be evacuated in that case. | 4378 // queue will be evacuated in that case. |
4397 | 4379 |
4398 // Grow the semi-space to two pages to make semi-space copy overwrite the | 4380 // Grow the semi-space to two pages to make semi-space copy overwrite the |
4399 // promotion queue, which will be at the end of the second page. | 4381 // promotion queue, which will be at the end of the second page. |
4400 intptr_t old_capacity = new_space->TotalCapacity(); | 4382 intptr_t old_capacity = new_space->TotalCapacity(); |
4401 new_space->Grow(); | 4383 new_space->Grow(); |
4402 CHECK(new_space->IsAtMaximumCapacity()); | 4384 CHECK(new_space->IsAtMaximumCapacity()); |
4403 CHECK(2 * old_capacity == new_space->TotalCapacity()); | 4385 CHECK(2 * old_capacity == new_space->TotalCapacity()); |
4404 | 4386 |
4405 // Call the scavenger two times to get an empty new space | 4387 // Call the scavenger two times to get an empty new space |
4406 heap->CollectGarbage(NEW_SPACE); | 4388 heap->CollectGarbage(NEW_SPACE); |
4407 heap->CollectGarbage(NEW_SPACE); | 4389 heap->CollectGarbage(NEW_SPACE); |
4408 | 4390 |
4409 // First create a few objects which will survive a scavenge, and will get | 4391 // First create a few objects which will survive a scavenge, and will get |
4410 // promoted to the old generation later on. These objects will create | 4392 // promoted to the old generation later on. These objects will create |
4411 // promotion queue entries at the end of the second semi-space page. | 4393 // promotion queue entries at the end of the second semi-space page. |
4412 const int number_handles = 12; | 4394 const int number_handles = 12; |
4413 Handle<FixedArray> handles[number_handles]; | 4395 Handle<FixedArray> handles[number_handles]; |
4414 for (int i = 0; i < number_handles; i++) { | 4396 for (int i = 0; i < number_handles; i++) { |
4415 handles[i] = i_isolate->factory()->NewFixedArray(1, NOT_TENURED); | 4397 handles[i] = isolate->factory()->NewFixedArray(1, NOT_TENURED); |
4416 } | 4398 } |
4417 heap->CollectGarbage(NEW_SPACE); | 4399 heap->CollectGarbage(NEW_SPACE); |
4418 | 4400 |
4419 // Create the first huge object which will exactly fit the first semi-space | 4401 // Create the first huge object which will exactly fit the first semi-space |
4420 // page. | 4402 // page. |
4421 int new_linear_size = | 4403 int new_linear_size = static_cast<int>( |
4422 static_cast<int>(*heap->new_space()->allocation_limit_address() - | 4404 *heap->new_space()->allocation_limit_address() - |
4423 *heap->new_space()->allocation_top_address()); | 4405 *heap->new_space()->allocation_top_address()); |
4424 int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize; | 4406 int length = new_linear_size / kPointerSize - FixedArray::kHeaderSize; |
4425 Handle<FixedArray> first = | 4407 Handle<FixedArray> first = |
4426 i_isolate->factory()->NewFixedArray(length, NOT_TENURED); | 4408 isolate->factory()->NewFixedArray(length, NOT_TENURED); |
4427 CHECK(heap->InNewSpace(*first)); | 4409 CHECK(heap->InNewSpace(*first)); |
4428 | 4410 |
4429 // Create the second huge object of maximum allocatable second semi-space | 4411 // Create the second huge object of maximum allocatable second semi-space |
4430 // page size. | 4412 // page size. |
4431 new_linear_size = | 4413 new_linear_size = static_cast<int>( |
4432 static_cast<int>(*heap->new_space()->allocation_limit_address() - | 4414 *heap->new_space()->allocation_limit_address() - |
4433 *heap->new_space()->allocation_top_address()); | 4415 *heap->new_space()->allocation_top_address()); |
4434 length = Page::kMaxRegularHeapObjectSize / kPointerSize - | 4416 length = Page::kMaxRegularHeapObjectSize / kPointerSize - |
4435 FixedArray::kHeaderSize; | 4417 FixedArray::kHeaderSize; |
4436 Handle<FixedArray> second = | 4418 Handle<FixedArray> second = |
4437 i_isolate->factory()->NewFixedArray(length, NOT_TENURED); | 4419 isolate->factory()->NewFixedArray(length, NOT_TENURED); |
4438 CHECK(heap->InNewSpace(*second)); | 4420 CHECK(heap->InNewSpace(*second)); |
4439 | 4421 |
4440 // This scavenge will corrupt memory if the promotion queue is not | 4422 // This scavenge will corrupt memory if the promotion queue is not evacuated. |
4441 // evacuated. | 4423 heap->CollectGarbage(NEW_SPACE); |
4442 heap->CollectGarbage(NEW_SPACE); | |
4443 } | |
4444 isolate->Dispose(); | |
4445 } | 4424 } |
4446 | 4425 |
4447 | 4426 |
4448 TEST(Regress388880) { | 4427 TEST(Regress388880) { |
4449 i::FLAG_expose_gc = true; | 4428 i::FLAG_expose_gc = true; |
4450 CcTest::InitializeVM(); | 4429 CcTest::InitializeVM(); |
4451 v8::HandleScope scope(CcTest::isolate()); | 4430 v8::HandleScope scope(CcTest::isolate()); |
4452 Isolate* isolate = CcTest::i_isolate(); | 4431 Isolate* isolate = CcTest::i_isolate(); |
4453 Factory* factory = isolate->factory(); | 4432 Factory* factory = isolate->factory(); |
4454 Heap* heap = isolate->heap(); | 4433 Heap* heap = isolate->heap(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4500 #ifdef DEBUG | 4479 #ifdef DEBUG |
4501 TEST(PathTracer) { | 4480 TEST(PathTracer) { |
4502 CcTest::InitializeVM(); | 4481 CcTest::InitializeVM(); |
4503 v8::HandleScope scope(CcTest::isolate()); | 4482 v8::HandleScope scope(CcTest::isolate()); |
4504 | 4483 |
4505 v8::Local<v8::Value> result = CompileRun("'abc'"); | 4484 v8::Local<v8::Value> result = CompileRun("'abc'"); |
4506 Handle<Object> o = v8::Utils::OpenHandle(*result); | 4485 Handle<Object> o = v8::Utils::OpenHandle(*result); |
4507 CcTest::i_isolate()->heap()->TracePathToObject(*o); | 4486 CcTest::i_isolate()->heap()->TracePathToObject(*o); |
4508 } | 4487 } |
4509 #endif // DEBUG | 4488 #endif // DEBUG |
OLD | NEW |