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