| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 | 2 |
| 3 #include <stdlib.h> | 3 #include <stdlib.h> |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "execution.h" | 7 #include "execution.h" |
| 8 #include "factory.h" | 8 #include "factory.h" |
| 9 #include "macro-assembler.h" | 9 #include "macro-assembler.h" |
| 10 #include "global-handles.h" | 10 #include "global-handles.h" |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 170 |
| 171 CheckFindCodeObject(); | 171 CheckFindCodeObject(); |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| 175 TEST(Tagging) { | 175 TEST(Tagging) { |
| 176 InitializeVM(); | 176 InitializeVM(); |
| 177 int request = 24; | 177 int request = 24; |
| 178 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); | 178 CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request))); |
| 179 CHECK(Smi::FromInt(42)->IsSmi()); | 179 CHECK(Smi::FromInt(42)->IsSmi()); |
| 180 CHECK(Failure::RetryAfterGC(request, NEW_SPACE)->IsFailure()); | 180 CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure()); |
| 181 CHECK_EQ(request, Failure::RetryAfterGC(request, NEW_SPACE)->requested()); | |
| 182 CHECK_EQ(NEW_SPACE, | 181 CHECK_EQ(NEW_SPACE, |
| 183 Failure::RetryAfterGC(request, NEW_SPACE)->allocation_space()); | 182 Failure::RetryAfterGC(NEW_SPACE)->allocation_space()); |
| 184 CHECK_EQ(OLD_POINTER_SPACE, | 183 CHECK_EQ(OLD_POINTER_SPACE, |
| 185 Failure::RetryAfterGC(request, | 184 Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space()); |
| 186 OLD_POINTER_SPACE)->allocation_space()); | |
| 187 CHECK(Failure::Exception()->IsFailure()); | 185 CHECK(Failure::Exception()->IsFailure()); |
| 188 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); | 186 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); |
| 189 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); | 187 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); |
| 190 } | 188 } |
| 191 | 189 |
| 192 | 190 |
| 193 TEST(GarbageCollection) { | 191 TEST(GarbageCollection) { |
| 194 InitializeVM(); | 192 InitializeVM(); |
| 195 | 193 |
| 196 v8::HandleScope sc; | 194 v8::HandleScope sc; |
| 197 // Check GC. | 195 // Check GC. |
| 198 int free_bytes = Heap::MaxObjectSizeInPagedSpace(); | 196 Heap::CollectGarbage(NEW_SPACE); |
| 199 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | |
| 200 | 197 |
| 201 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); | 198 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
| 202 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); | 199 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
| 203 Handle<String> prop_namex = Factory::LookupAsciiSymbol("theSlotx"); | 200 Handle<String> prop_namex = Factory::LookupAsciiSymbol("theSlotx"); |
| 204 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); | 201 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); |
| 205 | 202 |
| 206 { | 203 { |
| 207 v8::HandleScope inner_scope; | 204 v8::HandleScope inner_scope; |
| 208 // Allocate a function and keep it in global object's property. | 205 // Allocate a function and keep it in global object's property. |
| 209 Handle<JSFunction> function = | 206 Handle<JSFunction> function = |
| 210 Factory::NewFunction(name, Factory::undefined_value()); | 207 Factory::NewFunction(name, Factory::undefined_value()); |
| 211 Handle<Map> initial_map = | 208 Handle<Map> initial_map = |
| 212 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 209 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 213 function->set_initial_map(*initial_map); | 210 function->set_initial_map(*initial_map); |
| 214 Top::context()->global()->SetProperty(*name, *function, NONE); | 211 Top::context()->global()->SetProperty(*name, *function, NONE); |
| 215 // Allocate an object. Unrooted after leaving the scope. | 212 // Allocate an object. Unrooted after leaving the scope. |
| 216 Handle<JSObject> obj = Factory::NewJSObject(function); | 213 Handle<JSObject> obj = Factory::NewJSObject(function); |
| 217 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 214 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
| 218 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE); | 215 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE); |
| 219 | 216 |
| 220 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 217 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 221 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); | 218 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); |
| 222 } | 219 } |
| 223 | 220 |
| 224 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 221 Heap::CollectGarbage(NEW_SPACE); |
| 225 | 222 |
| 226 // Function should be alive. | 223 // Function should be alive. |
| 227 CHECK(Top::context()->global()->HasLocalProperty(*name)); | 224 CHECK(Top::context()->global()->HasLocalProperty(*name)); |
| 228 // Check function is retained. | 225 // Check function is retained. |
| 229 Object* func_value = Top::context()->global()->GetProperty(*name); | 226 Object* func_value = Top::context()->global()->GetProperty(*name); |
| 230 CHECK(func_value->IsJSFunction()); | 227 CHECK(func_value->IsJSFunction()); |
| 231 Handle<JSFunction> function(JSFunction::cast(func_value)); | 228 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 232 | 229 |
| 233 { | 230 { |
| 234 HandleScope inner_scope; | 231 HandleScope inner_scope; |
| 235 // Allocate another object, make it reachable from global. | 232 // Allocate another object, make it reachable from global. |
| 236 Handle<JSObject> obj = Factory::NewJSObject(function); | 233 Handle<JSObject> obj = Factory::NewJSObject(function); |
| 237 Top::context()->global()->SetProperty(*obj_name, *obj, NONE); | 234 Top::context()->global()->SetProperty(*obj_name, *obj, NONE); |
| 238 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); | 235 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
| 239 } | 236 } |
| 240 | 237 |
| 241 // After gc, it should survive. | 238 // After gc, it should survive. |
| 242 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 239 Heap::CollectGarbage(NEW_SPACE); |
| 243 | 240 |
| 244 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); | 241 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); |
| 245 CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject()); | 242 CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject()); |
| 246 JSObject* obj = | 243 JSObject* obj = |
| 247 JSObject::cast(Top::context()->global()->GetProperty(*obj_name)); | 244 JSObject::cast(Top::context()->global()->GetProperty(*obj_name)); |
| 248 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); | 245 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 249 } | 246 } |
| 250 | 247 |
| 251 | 248 |
| 252 static void VerifyStringAllocation(const char* string) { | 249 static void VerifyStringAllocation(const char* string) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); | 291 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
| 295 Handle<Object> u = Factory::NewNumber(1.12344); | 292 Handle<Object> u = Factory::NewNumber(1.12344); |
| 296 | 293 |
| 297 h1 = GlobalHandles::Create(*i); | 294 h1 = GlobalHandles::Create(*i); |
| 298 h2 = GlobalHandles::Create(*u); | 295 h2 = GlobalHandles::Create(*u); |
| 299 h3 = GlobalHandles::Create(*i); | 296 h3 = GlobalHandles::Create(*i); |
| 300 h4 = GlobalHandles::Create(*u); | 297 h4 = GlobalHandles::Create(*u); |
| 301 } | 298 } |
| 302 | 299 |
| 303 // after gc, it should survive | 300 // after gc, it should survive |
| 304 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 301 Heap::CollectGarbage(NEW_SPACE); |
| 305 | 302 |
| 306 CHECK((*h1)->IsString()); | 303 CHECK((*h1)->IsString()); |
| 307 CHECK((*h2)->IsHeapNumber()); | 304 CHECK((*h2)->IsHeapNumber()); |
| 308 CHECK((*h3)->IsString()); | 305 CHECK((*h3)->IsString()); |
| 309 CHECK((*h4)->IsHeapNumber()); | 306 CHECK((*h4)->IsHeapNumber()); |
| 310 | 307 |
| 311 CHECK_EQ(*h3, *h1); | 308 CHECK_EQ(*h3, *h1); |
| 312 GlobalHandles::Destroy(h1.location()); | 309 GlobalHandles::Destroy(h1.location()); |
| 313 GlobalHandles::Destroy(h3.location()); | 310 GlobalHandles::Destroy(h3.location()); |
| 314 | 311 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 { | 372 { |
| 376 HandleScope scope; | 373 HandleScope scope; |
| 377 | 374 |
| 378 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); | 375 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
| 379 Handle<Object> u = Factory::NewNumber(1.12344); | 376 Handle<Object> u = Factory::NewNumber(1.12344); |
| 380 | 377 |
| 381 h1 = GlobalHandles::Create(*i); | 378 h1 = GlobalHandles::Create(*i); |
| 382 h2 = GlobalHandles::Create(*u); | 379 h2 = GlobalHandles::Create(*u); |
| 383 } | 380 } |
| 384 | 381 |
| 385 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 382 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 386 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 383 Heap::CollectGarbage(NEW_SPACE); |
| 387 // Make sure the object is promoted. | 384 // Make sure the object is promoted. |
| 388 | 385 |
| 389 GlobalHandles::MakeWeak(h2.location(), | 386 GlobalHandles::MakeWeak(h2.location(), |
| 390 reinterpret_cast<void*>(1234), | 387 reinterpret_cast<void*>(1234), |
| 391 &TestWeakGlobalHandleCallback); | 388 &TestWeakGlobalHandleCallback); |
| 392 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 389 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
| 393 CHECK(!GlobalHandles::IsNearDeath(h2.location())); | 390 CHECK(!GlobalHandles::IsNearDeath(h2.location())); |
| 394 | 391 |
| 395 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 392 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 396 | 393 |
| 397 CHECK((*h1)->IsString()); | 394 CHECK((*h1)->IsString()); |
| 398 | 395 |
| 399 CHECK(WeakPointerCleared); | 396 CHECK(WeakPointerCleared); |
| 400 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 397 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
| 401 | 398 |
| 402 GlobalHandles::Destroy(h1.location()); | 399 GlobalHandles::Destroy(h1.location()); |
| 403 } | 400 } |
| 404 | 401 |
| 405 TEST(DeleteWeakGlobalHandle) { | 402 TEST(DeleteWeakGlobalHandle) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 419 GlobalHandles::MakeWeak(h.location(), | 416 GlobalHandles::MakeWeak(h.location(), |
| 420 reinterpret_cast<void*>(1234), | 417 reinterpret_cast<void*>(1234), |
| 421 &TestWeakGlobalHandleCallback); | 418 &TestWeakGlobalHandleCallback); |
| 422 | 419 |
| 423 // Scanvenge does not recognize weak reference. | 420 // Scanvenge does not recognize weak reference. |
| 424 Heap::PerformScavenge(); | 421 Heap::PerformScavenge(); |
| 425 | 422 |
| 426 CHECK(!WeakPointerCleared); | 423 CHECK(!WeakPointerCleared); |
| 427 | 424 |
| 428 // Mark-compact treats weak reference properly. | 425 // Mark-compact treats weak reference properly. |
| 429 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 426 Heap::CollectGarbage(OLD_POINTER_SPACE); |
| 430 | 427 |
| 431 CHECK(WeakPointerCleared); | 428 CHECK(WeakPointerCleared); |
| 432 } | 429 } |
| 433 | 430 |
| 434 static const char* not_so_random_string_table[] = { | 431 static const char* not_so_random_string_table[] = { |
| 435 "abstract", | 432 "abstract", |
| 436 "boolean", | 433 "boolean", |
| 437 "break", | 434 "break", |
| 438 "byte", | 435 "byte", |
| 439 "case", | 436 "case", |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); | 804 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); |
| 808 | 805 |
| 809 CHECK_EQ(objs_count, next_objs_index); | 806 CHECK_EQ(objs_count, next_objs_index); |
| 810 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); | 807 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); |
| 811 } | 808 } |
| 812 | 809 |
| 813 | 810 |
| 814 TEST(LargeObjectSpaceContains) { | 811 TEST(LargeObjectSpaceContains) { |
| 815 InitializeVM(); | 812 InitializeVM(); |
| 816 | 813 |
| 817 int free_bytes = Heap::MaxObjectSizeInPagedSpace(); | 814 Heap::CollectGarbage(NEW_SPACE); |
| 818 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | |
| 819 | 815 |
| 820 Address current_top = Heap::new_space()->top(); | 816 Address current_top = Heap::new_space()->top(); |
| 821 Page* page = Page::FromAddress(current_top); | 817 Page* page = Page::FromAddress(current_top); |
| 822 Address current_page = page->address(); | 818 Address current_page = page->address(); |
| 823 Address next_page = current_page + Page::kPageSize; | 819 Address next_page = current_page + Page::kPageSize; |
| 824 int bytes_to_page = static_cast<int>(next_page - current_top); | 820 int bytes_to_page = static_cast<int>(next_page - current_top); |
| 825 if (bytes_to_page <= FixedArray::kHeaderSize) { | 821 if (bytes_to_page <= FixedArray::kHeaderSize) { |
| 826 // Alas, need to cross another page to be able to | 822 // Alas, need to cross another page to be able to |
| 827 // put desired value. | 823 // put desired value. |
| 828 next_page += Page::kPageSize; | 824 next_page += Page::kPageSize; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 Heap::CollectAllGarbage(true); | 990 Heap::CollectAllGarbage(true); |
| 995 | 991 |
| 996 // foo should no longer be in the compilation cache | 992 // foo should no longer be in the compilation cache |
| 997 CHECK(!function->shared()->is_compiled()); | 993 CHECK(!function->shared()->is_compiled()); |
| 998 CHECK(!function->is_compiled()); | 994 CHECK(!function->is_compiled()); |
| 999 // Call foo to get it recompiled. | 995 // Call foo to get it recompiled. |
| 1000 CompileRun("foo()"); | 996 CompileRun("foo()"); |
| 1001 CHECK(function->shared()->is_compiled()); | 997 CHECK(function->shared()->is_compiled()); |
| 1002 CHECK(function->is_compiled()); | 998 CHECK(function->is_compiled()); |
| 1003 } | 999 } |
| OLD | NEW |