| 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 value = Heap::NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); | 142 value = Heap::NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); |
| 143 CHECK(value->IsHeapNumber()); | 143 CHECK(value->IsHeapNumber()); |
| 144 CHECK(value->IsNumber()); | 144 CHECK(value->IsNumber()); |
| 145 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), | 145 CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1), |
| 146 value->Number()); | 146 value->Number()); |
| 147 | 147 |
| 148 // nan oddball checks | 148 // nan oddball checks |
| 149 CHECK(Heap::nan_value()->IsNumber()); | 149 CHECK(Heap::nan_value()->IsNumber()); |
| 150 CHECK(isnan(Heap::nan_value()->Number())); | 150 CHECK(isnan(Heap::nan_value()->Number())); |
| 151 | 151 |
| 152 Object* str = Heap::AllocateStringFromAscii(CStrVector("fisk hest ")); | 152 Handle<String> s = Factory::NewStringFromAscii(CStrVector("fisk hest ")); |
| 153 if (!str->IsFailure()) { | 153 CHECK(s->IsString()); |
| 154 String* s = String::cast(str); | 154 CHECK_EQ(10, s->length()); |
| 155 CHECK(s->IsString()); | |
| 156 CHECK_EQ(10, s->length()); | |
| 157 } else { | |
| 158 CHECK(false); | |
| 159 } | |
| 160 | 155 |
| 161 String* object_symbol = String::cast(Heap::Object_symbol()); | 156 String* object_symbol = String::cast(Heap::Object_symbol()); |
| 162 CHECK(Top::context()->global()->HasLocalProperty(object_symbol)); | 157 CHECK(Top::context()->global()->HasLocalProperty(object_symbol)); |
| 163 | 158 |
| 164 // Check ToString for oddballs | 159 // Check ToString for oddballs |
| 165 CheckOddball(Heap::true_value(), "true"); | 160 CheckOddball(Heap::true_value(), "true"); |
| 166 CheckOddball(Heap::false_value(), "false"); | 161 CheckOddball(Heap::false_value(), "false"); |
| 167 CheckOddball(Heap::null_value(), "null"); | 162 CheckOddball(Heap::null_value(), "null"); |
| 168 CheckOddball(Heap::undefined_value(), "undefined"); | 163 CheckOddball(Heap::undefined_value(), "undefined"); |
| 169 | 164 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 194 CHECK(Failure::Exception()->IsFailure()); | 189 CHECK(Failure::Exception()->IsFailure()); |
| 195 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); | 190 CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi()); |
| 196 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); | 191 CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi()); |
| 197 } | 192 } |
| 198 | 193 |
| 199 | 194 |
| 200 TEST(GarbageCollection) { | 195 TEST(GarbageCollection) { |
| 201 InitializeVM(); | 196 InitializeVM(); |
| 202 | 197 |
| 203 v8::HandleScope sc; | 198 v8::HandleScope sc; |
| 204 // check GC when heap is empty | 199 // Check GC. |
| 205 int free_bytes = Heap::MaxObjectSizeInPagedSpace(); | 200 int free_bytes = Heap::MaxObjectSizeInPagedSpace(); |
| 206 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 201 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); |
| 207 | 202 |
| 208 // allocate a function and keep it in global object's property | 203 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
| 209 String* func_name = String::cast(Heap::LookupAsciiSymbol("theFunction")); | 204 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
| 210 SharedFunctionInfo* function_share = | 205 Handle<String> prop_namex = Factory::LookupAsciiSymbol("theSlotx"); |
| 211 SharedFunctionInfo::cast(Heap::AllocateSharedFunctionInfo(func_name)); | 206 Handle<String> obj_name = Factory::LookupAsciiSymbol("theObject"); |
| 212 JSFunction* function = | |
| 213 JSFunction::cast(Heap::AllocateFunction(*Top::function_map(), | |
| 214 function_share, | |
| 215 Heap::undefined_value())); | |
| 216 Map* initial_map = | |
| 217 Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)); | |
| 218 function->set_initial_map(initial_map); | |
| 219 Top::context()->global()->SetProperty(func_name, function, NONE); | |
| 220 | 207 |
| 221 // allocate an object, but it is unrooted | 208 { |
| 222 String* prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | 209 v8::HandleScope inner_scope; |
| 223 String* prop_namex = String::cast(Heap::LookupAsciiSymbol("theSlotx")); | 210 // Allocate a function and keep it in global object's property. |
| 224 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(function)); | 211 Handle<JSFunction> function = |
| 225 obj->SetProperty(prop_name, Smi::FromInt(23), NONE); | 212 Factory::NewFunction(name, Factory::undefined_value()); |
| 226 obj->SetProperty(prop_namex, Smi::FromInt(24), NONE); | 213 Handle<Map> initial_map = |
| 214 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 215 function->set_initial_map(*initial_map); |
| 216 Top::context()->global()->SetProperty(*name, *function, NONE); |
| 217 // Allocate an object. Unrooted after leaving the scope. |
| 218 Handle<JSObject> obj = Factory::NewJSObject(function); |
| 219 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
| 220 obj->SetProperty(*prop_namex, Smi::FromInt(24), NONE); |
| 227 | 221 |
| 228 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(prop_name)); | 222 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 229 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(prop_namex)); | 223 CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex)); |
| 224 } |
| 230 | 225 |
| 231 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 226 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); |
| 232 | 227 |
| 233 // function should be alive, func_name might be invalid after GC | 228 // Function should be alive. |
| 234 func_name = String::cast(Heap::LookupAsciiSymbol("theFunction")); | 229 CHECK(Top::context()->global()->HasLocalProperty(*name)); |
| 235 CHECK(Top::context()->global()->HasLocalProperty(func_name)); | 230 // Check function is retained. |
| 236 // check function is retained | 231 Object* func_value = Top::context()->global()->GetProperty(*name); |
| 237 Object* func_value = Top::context()->global()->GetProperty(func_name); | |
| 238 CHECK(func_value->IsJSFunction()); | 232 CHECK(func_value->IsJSFunction()); |
| 239 // old function pointer may not be valid | 233 Handle<JSFunction> function(JSFunction::cast(func_value)); |
| 240 function = JSFunction::cast(func_value); | |
| 241 | 234 |
| 242 // allocate another object, make it reachable from global | 235 { |
| 243 obj = JSObject::cast(Heap::AllocateJSObject(function)); | 236 HandleScope inner_scope; |
| 244 String* obj_name = String::cast(Heap::LookupAsciiSymbol("theObject")); | 237 // Allocate another object, make it reachable from global. |
| 245 Top::context()->global()->SetProperty(obj_name, obj, NONE); | 238 Handle<JSObject> obj = Factory::NewJSObject(function); |
| 246 // set property | 239 Top::context()->global()->SetProperty(*obj_name, *obj, NONE); |
| 247 prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | 240 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
| 248 obj->SetProperty(prop_name, Smi::FromInt(23), NONE); | 241 } |
| 249 | 242 |
| 250 // after gc, it should survive | 243 // After gc, it should survive. |
| 251 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); | 244 CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE)); |
| 252 | 245 |
| 253 obj_name = String::cast(Heap::LookupAsciiSymbol("theObject")); | 246 CHECK(Top::context()->global()->HasLocalProperty(*obj_name)); |
| 254 CHECK(Top::context()->global()->HasLocalProperty(obj_name)); | 247 CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject()); |
| 255 CHECK(Top::context()->global()->GetProperty(obj_name)->IsJSObject()); | 248 JSObject* obj = |
| 256 obj = JSObject::cast(Top::context()->global()->GetProperty(obj_name)); | 249 JSObject::cast(Top::context()->global()->GetProperty(*obj_name)); |
| 257 prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | 250 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 258 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(prop_name)); | |
| 259 } | 251 } |
| 260 | 252 |
| 261 | 253 |
| 262 static void VerifyStringAllocation(const char* string) { | 254 static void VerifyStringAllocation(const char* string) { |
| 263 String* s = String::cast(Heap::AllocateStringFromUtf8(CStrVector(string))); | 255 v8::HandleScope scope; |
| 256 Handle<String> s = Factory::NewStringFromUtf8(CStrVector(string)); |
| 264 CHECK_EQ(StrLength(string), s->length()); | 257 CHECK_EQ(StrLength(string), s->length()); |
| 265 for (int index = 0; index < s->length(); index++) { | 258 for (int index = 0; index < s->length(); index++) { |
| 266 CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index)); } | 259 CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index)); |
| 260 } |
| 267 } | 261 } |
| 268 | 262 |
| 269 | 263 |
| 270 TEST(String) { | 264 TEST(String) { |
| 271 InitializeVM(); | 265 InitializeVM(); |
| 272 | 266 |
| 273 VerifyStringAllocation("a"); | 267 VerifyStringAllocation("a"); |
| 274 VerifyStringAllocation("ab"); | 268 VerifyStringAllocation("ab"); |
| 275 VerifyStringAllocation("abc"); | 269 VerifyStringAllocation("abc"); |
| 276 VerifyStringAllocation("abcd"); | 270 VerifyStringAllocation("abcd"); |
| 277 VerifyStringAllocation("fiskerdrengen er paa havet"); | 271 VerifyStringAllocation("fiskerdrengen er paa havet"); |
| 278 } | 272 } |
| 279 | 273 |
| 280 | 274 |
| 281 TEST(LocalHandles) { | 275 TEST(LocalHandles) { |
| 282 InitializeVM(); | 276 InitializeVM(); |
| 283 | 277 |
| 284 v8::HandleScope scope; | 278 v8::HandleScope scope; |
| 285 const char* name = "Kasper the spunky"; | 279 const char* name = "Kasper the spunky"; |
| 286 Handle<String> string = Factory::NewStringFromAscii(CStrVector(name)); | 280 Handle<String> string = Factory::NewStringFromAscii(CStrVector(name)); |
| 287 CHECK_EQ(StrLength(name), string->length()); | 281 CHECK_EQ(StrLength(name), string->length()); |
| 288 } | 282 } |
| 289 | 283 |
| 290 | 284 |
| 291 TEST(GlobalHandles) { | 285 TEST(GlobalHandles) { |
| 292 InitializeVM(); | 286 InitializeVM(); |
| 293 | 287 |
| 294 Object* i = Heap::AllocateStringFromAscii(CStrVector("fisk")); | 288 Handle<Object> h1; |
| 295 Object* u = Heap::AllocateHeapNumber(1.12344); | 289 Handle<Object> h2; |
| 290 Handle<Object> h3; |
| 291 Handle<Object> h4; |
| 296 | 292 |
| 297 Handle<Object> h1 = GlobalHandles::Create(i); | 293 { |
| 298 Handle<Object> h2 = GlobalHandles::Create(u); | 294 HandleScope scope; |
| 299 Handle<Object> h3 = GlobalHandles::Create(i); | 295 |
| 300 Handle<Object> h4 = GlobalHandles::Create(u); | 296 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
| 297 Handle<Object> u = Factory::NewNumber(1.12344); |
| 298 |
| 299 h1 = GlobalHandles::Create(*i); |
| 300 h2 = GlobalHandles::Create(*u); |
| 301 h3 = GlobalHandles::Create(*i); |
| 302 h4 = GlobalHandles::Create(*u); |
| 303 } |
| 301 | 304 |
| 302 // after gc, it should survive | 305 // after gc, it should survive |
| 303 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 306 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); |
| 304 | 307 |
| 305 CHECK((*h1)->IsString()); | 308 CHECK((*h1)->IsString()); |
| 306 CHECK((*h2)->IsHeapNumber()); | 309 CHECK((*h2)->IsHeapNumber()); |
| 307 CHECK((*h3)->IsString()); | 310 CHECK((*h3)->IsString()); |
| 308 CHECK((*h4)->IsHeapNumber()); | 311 CHECK((*h4)->IsHeapNumber()); |
| 309 | 312 |
| 310 CHECK_EQ(*h3, *h1); | 313 CHECK_EQ(*h3, *h1); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 324 USE(handle); | 327 USE(handle); |
| 325 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; | 328 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; |
| 326 } | 329 } |
| 327 | 330 |
| 328 | 331 |
| 329 TEST(WeakGlobalHandlesScavenge) { | 332 TEST(WeakGlobalHandlesScavenge) { |
| 330 InitializeVM(); | 333 InitializeVM(); |
| 331 | 334 |
| 332 WeakPointerCleared = false; | 335 WeakPointerCleared = false; |
| 333 | 336 |
| 334 Object* i = Heap::AllocateStringFromAscii(CStrVector("fisk")); | 337 Handle<Object> h1; |
| 335 Object* u = Heap::AllocateHeapNumber(1.12344); | 338 Handle<Object> h2; |
| 336 | 339 |
| 337 Handle<Object> h1 = GlobalHandles::Create(i); | 340 { |
| 338 Handle<Object> h2 = GlobalHandles::Create(u); | 341 HandleScope scope; |
| 342 |
| 343 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
| 344 Handle<Object> u = Factory::NewNumber(1.12344); |
| 345 |
| 346 h1 = GlobalHandles::Create(*i); |
| 347 h2 = GlobalHandles::Create(*u); |
| 348 } |
| 339 | 349 |
| 340 GlobalHandles::MakeWeak(h2.location(), | 350 GlobalHandles::MakeWeak(h2.location(), |
| 341 reinterpret_cast<void*>(1234), | 351 reinterpret_cast<void*>(1234), |
| 342 &TestWeakGlobalHandleCallback); | 352 &TestWeakGlobalHandleCallback); |
| 343 | 353 |
| 344 // Scavenge treats weak pointers as normal roots. | 354 // Scavenge treats weak pointers as normal roots. |
| 345 Heap::PerformScavenge(); | 355 Heap::PerformScavenge(); |
| 346 | 356 |
| 347 CHECK((*h1)->IsString()); | 357 CHECK((*h1)->IsString()); |
| 348 CHECK((*h2)->IsHeapNumber()); | 358 CHECK((*h2)->IsHeapNumber()); |
| 349 | 359 |
| 350 CHECK(!WeakPointerCleared); | 360 CHECK(!WeakPointerCleared); |
| 351 CHECK(!GlobalHandles::IsNearDeath(h2.location())); | 361 CHECK(!GlobalHandles::IsNearDeath(h2.location())); |
| 352 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 362 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
| 353 | 363 |
| 354 GlobalHandles::Destroy(h1.location()); | 364 GlobalHandles::Destroy(h1.location()); |
| 355 GlobalHandles::Destroy(h2.location()); | 365 GlobalHandles::Destroy(h2.location()); |
| 356 } | 366 } |
| 357 | 367 |
| 358 | 368 |
| 359 TEST(WeakGlobalHandlesMark) { | 369 TEST(WeakGlobalHandlesMark) { |
| 360 InitializeVM(); | 370 InitializeVM(); |
| 361 | 371 |
| 362 WeakPointerCleared = false; | 372 WeakPointerCleared = false; |
| 363 | 373 |
| 364 Object* i = Heap::AllocateStringFromAscii(CStrVector("fisk")); | 374 Handle<Object> h1; |
| 365 Object* u = Heap::AllocateHeapNumber(1.12344); | 375 Handle<Object> h2; |
| 366 | 376 |
| 367 Handle<Object> h1 = GlobalHandles::Create(i); | 377 { |
| 368 Handle<Object> h2 = GlobalHandles::Create(u); | 378 HandleScope scope; |
| 379 |
| 380 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
| 381 Handle<Object> u = Factory::NewNumber(1.12344); |
| 382 |
| 383 h1 = GlobalHandles::Create(*i); |
| 384 h2 = GlobalHandles::Create(*u); |
| 385 } |
| 369 | 386 |
| 370 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); | 387 CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE)); |
| 371 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); | 388 CHECK(Heap::CollectGarbage(0, NEW_SPACE)); |
| 372 // Make sure the object is promoted. | 389 // Make sure the object is promoted. |
| 373 | 390 |
| 374 GlobalHandles::MakeWeak(h2.location(), | 391 GlobalHandles::MakeWeak(h2.location(), |
| 375 reinterpret_cast<void*>(1234), | 392 reinterpret_cast<void*>(1234), |
| 376 &TestWeakGlobalHandleCallback); | 393 &TestWeakGlobalHandleCallback); |
| 377 CHECK(!GlobalHandles::IsNearDeath(h1.location())); | 394 CHECK(!GlobalHandles::IsNearDeath(h1.location())); |
| 378 CHECK(!GlobalHandles::IsNearDeath(h2.location())); | 395 CHECK(!GlobalHandles::IsNearDeath(h2.location())); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 394 void* id) { | 411 void* id) { |
| 395 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; | 412 if (1234 == reinterpret_cast<intptr_t>(id)) WeakPointerCleared = true; |
| 396 handle.Dispose(); | 413 handle.Dispose(); |
| 397 } | 414 } |
| 398 | 415 |
| 399 TEST(DeleteWeakGlobalHandle) { | 416 TEST(DeleteWeakGlobalHandle) { |
| 400 InitializeVM(); | 417 InitializeVM(); |
| 401 | 418 |
| 402 WeakPointerCleared = false; | 419 WeakPointerCleared = false; |
| 403 | 420 |
| 404 Object* i = Heap::AllocateStringFromAscii(CStrVector("fisk")); | 421 Handle<Object> h; |
| 405 Handle<Object> h = GlobalHandles::Create(i); | 422 |
| 423 { |
| 424 HandleScope scope; |
| 425 |
| 426 Handle<Object> i = Factory::NewStringFromAscii(CStrVector("fisk")); |
| 427 h = GlobalHandles::Create(*i); |
| 428 } |
| 406 | 429 |
| 407 GlobalHandles::MakeWeak(h.location(), | 430 GlobalHandles::MakeWeak(h.location(), |
| 408 reinterpret_cast<void*>(1234), | 431 reinterpret_cast<void*>(1234), |
| 409 &TestDeleteWeakGlobalHandleCallback); | 432 &TestDeleteWeakGlobalHandleCallback); |
| 410 | 433 |
| 411 // Scanvenge does not recognize weak reference. | 434 // Scanvenge does not recognize weak reference. |
| 412 Heap::PerformScavenge(); | 435 Heap::PerformScavenge(); |
| 413 | 436 |
| 414 CHECK(!WeakPointerCleared); | 437 CHECK(!WeakPointerCleared); |
| 415 | 438 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 | 525 |
| 503 CheckSymbols(not_so_random_string_table); | 526 CheckSymbols(not_so_random_string_table); |
| 504 CheckSymbols(not_so_random_string_table); | 527 CheckSymbols(not_so_random_string_table); |
| 505 } | 528 } |
| 506 | 529 |
| 507 | 530 |
| 508 TEST(FunctionAllocation) { | 531 TEST(FunctionAllocation) { |
| 509 InitializeVM(); | 532 InitializeVM(); |
| 510 | 533 |
| 511 v8::HandleScope sc; | 534 v8::HandleScope sc; |
| 512 String* name = String::cast(Heap::LookupAsciiSymbol("theFunction")); | 535 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
| 513 SharedFunctionInfo* function_share = | 536 Handle<JSFunction> function = |
| 514 SharedFunctionInfo::cast(Heap::AllocateSharedFunctionInfo(name)); | 537 Factory::NewFunction(name, Factory::undefined_value()); |
| 515 JSFunction* function = | 538 Handle<Map> initial_map = |
| 516 JSFunction::cast(Heap::AllocateFunction(*Top::function_map(), | 539 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 517 function_share, | 540 function->set_initial_map(*initial_map); |
| 518 Heap::undefined_value())); | |
| 519 Map* initial_map = | |
| 520 Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)); | |
| 521 function->set_initial_map(initial_map); | |
| 522 | 541 |
| 523 String* prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | 542 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
| 524 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(function)); | 543 Handle<JSObject> obj = Factory::NewJSObject(function); |
| 525 obj->SetProperty(prop_name, Smi::FromInt(23), NONE); | 544 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
| 526 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(prop_name)); | 545 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 527 // Check that we can add properties to function objects. | 546 // Check that we can add properties to function objects. |
| 528 function->SetProperty(prop_name, Smi::FromInt(24), NONE); | 547 function->SetProperty(*prop_name, Smi::FromInt(24), NONE); |
| 529 CHECK_EQ(Smi::FromInt(24), function->GetProperty(prop_name)); | 548 CHECK_EQ(Smi::FromInt(24), function->GetProperty(*prop_name)); |
| 530 } | 549 } |
| 531 | 550 |
| 532 | 551 |
| 533 TEST(ObjectProperties) { | 552 TEST(ObjectProperties) { |
| 534 InitializeVM(); | 553 InitializeVM(); |
| 535 | 554 |
| 536 v8::HandleScope sc; | 555 v8::HandleScope sc; |
| 537 JSFunction* constructor = | 556 String* object_symbol = String::cast(Heap::Object_symbol()); |
| 538 JSFunction::cast( | 557 JSFunction* object_function = |
| 539 Top::context()->global()->GetProperty(String::cast( | 558 JSFunction::cast(Top::context()->global()->GetProperty(object_symbol)); |
| 540 Heap::Object_symbol()))); | 559 Handle<JSFunction> constructor(object_function); |
| 541 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(constructor)); | 560 Handle<JSObject> obj = Factory::NewJSObject(constructor); |
| 542 String* first = String::cast(Heap::LookupAsciiSymbol("first")); | 561 Handle<String> first = Factory::LookupAsciiSymbol("first"); |
| 543 String* second = String::cast(Heap::LookupAsciiSymbol("second")); | 562 Handle<String> second = Factory::LookupAsciiSymbol("second"); |
| 544 | 563 |
| 545 // check for empty | 564 // check for empty |
| 546 CHECK(!obj->HasLocalProperty(first)); | 565 CHECK(!obj->HasLocalProperty(*first)); |
| 547 | 566 |
| 548 // add first | 567 // add first |
| 549 obj->SetProperty(first, Smi::FromInt(1), NONE); | 568 obj->SetProperty(*first, Smi::FromInt(1), NONE); |
| 550 CHECK(obj->HasLocalProperty(first)); | 569 CHECK(obj->HasLocalProperty(*first)); |
| 551 | 570 |
| 552 // delete first | 571 // delete first |
| 553 CHECK(obj->DeleteProperty(first, JSObject::NORMAL_DELETION)); | 572 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); |
| 554 CHECK(!obj->HasLocalProperty(first)); | 573 CHECK(!obj->HasLocalProperty(*first)); |
| 555 | 574 |
| 556 // add first and then second | 575 // add first and then second |
| 557 obj->SetProperty(first, Smi::FromInt(1), NONE); | 576 obj->SetProperty(*first, Smi::FromInt(1), NONE); |
| 558 obj->SetProperty(second, Smi::FromInt(2), NONE); | 577 obj->SetProperty(*second, Smi::FromInt(2), NONE); |
| 559 CHECK(obj->HasLocalProperty(first)); | 578 CHECK(obj->HasLocalProperty(*first)); |
| 560 CHECK(obj->HasLocalProperty(second)); | 579 CHECK(obj->HasLocalProperty(*second)); |
| 561 | 580 |
| 562 // delete first and then second | 581 // delete first and then second |
| 563 CHECK(obj->DeleteProperty(first, JSObject::NORMAL_DELETION)); | 582 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); |
| 564 CHECK(obj->HasLocalProperty(second)); | 583 CHECK(obj->HasLocalProperty(*second)); |
| 565 CHECK(obj->DeleteProperty(second, JSObject::NORMAL_DELETION)); | 584 CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); |
| 566 CHECK(!obj->HasLocalProperty(first)); | 585 CHECK(!obj->HasLocalProperty(*first)); |
| 567 CHECK(!obj->HasLocalProperty(second)); | 586 CHECK(!obj->HasLocalProperty(*second)); |
| 568 | 587 |
| 569 // add first and then second | 588 // add first and then second |
| 570 obj->SetProperty(first, Smi::FromInt(1), NONE); | 589 obj->SetProperty(*first, Smi::FromInt(1), NONE); |
| 571 obj->SetProperty(second, Smi::FromInt(2), NONE); | 590 obj->SetProperty(*second, Smi::FromInt(2), NONE); |
| 572 CHECK(obj->HasLocalProperty(first)); | 591 CHECK(obj->HasLocalProperty(*first)); |
| 573 CHECK(obj->HasLocalProperty(second)); | 592 CHECK(obj->HasLocalProperty(*second)); |
| 574 | 593 |
| 575 // delete second and then first | 594 // delete second and then first |
| 576 CHECK(obj->DeleteProperty(second, JSObject::NORMAL_DELETION)); | 595 CHECK(obj->DeleteProperty(*second, JSObject::NORMAL_DELETION)); |
| 577 CHECK(obj->HasLocalProperty(first)); | 596 CHECK(obj->HasLocalProperty(*first)); |
| 578 CHECK(obj->DeleteProperty(first, JSObject::NORMAL_DELETION)); | 597 CHECK(obj->DeleteProperty(*first, JSObject::NORMAL_DELETION)); |
| 579 CHECK(!obj->HasLocalProperty(first)); | 598 CHECK(!obj->HasLocalProperty(*first)); |
| 580 CHECK(!obj->HasLocalProperty(second)); | 599 CHECK(!obj->HasLocalProperty(*second)); |
| 581 | 600 |
| 582 // check string and symbol match | 601 // check string and symbol match |
| 583 static const char* string1 = "fisk"; | 602 static const char* string1 = "fisk"; |
| 584 String* s1 = | 603 Handle<String> s1 = Factory::NewStringFromAscii(CStrVector(string1)); |
| 585 String::cast(Heap::AllocateStringFromAscii(CStrVector(string1))); | 604 obj->SetProperty(*s1, Smi::FromInt(1), NONE); |
| 586 obj->SetProperty(s1, Smi::FromInt(1), NONE); | 605 Handle<String> s1_symbol = Factory::LookupAsciiSymbol(string1); |
| 587 CHECK(obj->HasLocalProperty(String::cast(Heap::LookupAsciiSymbol(string1)))); | 606 CHECK(obj->HasLocalProperty(*s1_symbol)); |
| 588 | 607 |
| 589 // check symbol and string match | 608 // check symbol and string match |
| 590 static const char* string2 = "fugl"; | 609 static const char* string2 = "fugl"; |
| 591 String* s2 = String::cast(Heap::LookupAsciiSymbol(string2)); | 610 Handle<String> s2_symbol = Factory::LookupAsciiSymbol(string2); |
| 592 obj->SetProperty(s2, Smi::FromInt(1), NONE); | 611 obj->SetProperty(*s2_symbol, Smi::FromInt(1), NONE); |
| 593 CHECK(obj->HasLocalProperty( | 612 Handle<String> s2 = Factory::NewStringFromAscii(CStrVector(string2)); |
| 594 String::cast(Heap::AllocateStringFromAscii(CStrVector(string2))))); | 613 CHECK(obj->HasLocalProperty(*s2)); |
| 595 } | 614 } |
| 596 | 615 |
| 597 | 616 |
| 598 TEST(JSObjectMaps) { | 617 TEST(JSObjectMaps) { |
| 599 InitializeVM(); | 618 InitializeVM(); |
| 600 | 619 |
| 601 v8::HandleScope sc; | 620 v8::HandleScope sc; |
| 602 String* name = String::cast(Heap::LookupAsciiSymbol("theFunction")); | 621 Handle<String> name = Factory::LookupAsciiSymbol("theFunction"); |
| 603 SharedFunctionInfo* function_share = | 622 Handle<JSFunction> function = |
| 604 SharedFunctionInfo::cast(Heap::AllocateSharedFunctionInfo(name)); | 623 Factory::NewFunction(name, Factory::undefined_value()); |
| 605 JSFunction* function = | 624 Handle<Map> initial_map = |
| 606 JSFunction::cast(Heap::AllocateFunction(*Top::function_map(), | 625 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 607 function_share, | 626 function->set_initial_map(*initial_map); |
| 608 Heap::undefined_value())); | 627 |
| 609 Map* initial_map = | 628 Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot"); |
| 610 Map::cast(Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize)); | 629 Handle<JSObject> obj = Factory::NewJSObject(function); |
| 611 function->set_initial_map(initial_map); | |
| 612 String* prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot")); | |
| 613 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(function)); | |
| 614 | 630 |
| 615 // Set a propery | 631 // Set a propery |
| 616 obj->SetProperty(prop_name, Smi::FromInt(23), NONE); | 632 obj->SetProperty(*prop_name, Smi::FromInt(23), NONE); |
| 617 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(prop_name)); | 633 CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name)); |
| 618 | 634 |
| 619 // Check the map has changed | 635 // Check the map has changed |
| 620 CHECK(initial_map != obj->map()); | 636 CHECK(*initial_map != obj->map()); |
| 621 } | 637 } |
| 622 | 638 |
| 623 | 639 |
| 624 TEST(JSArray) { | 640 TEST(JSArray) { |
| 625 InitializeVM(); | 641 InitializeVM(); |
| 626 | 642 |
| 627 v8::HandleScope sc; | 643 v8::HandleScope sc; |
| 628 String* name = String::cast(Heap::LookupAsciiSymbol("Array")); | 644 Handle<String> name = Factory::LookupAsciiSymbol("Array"); |
| 629 JSFunction* function = | 645 Handle<JSFunction> function = Handle<JSFunction>( |
| 630 JSFunction::cast(Top::context()->global()->GetProperty(name)); | 646 JSFunction::cast(Top::context()->global()->GetProperty(*name))); |
| 631 | 647 |
| 632 // Allocate the object. | 648 // Allocate the object. |
| 633 JSArray* array = JSArray::cast(Heap::AllocateJSObject(function)); | 649 Handle<JSObject> object = Factory::NewJSObject(function); |
| 650 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 634 array->Initialize(0); | 651 array->Initialize(0); |
| 635 | 652 |
| 636 // Set array length to 0. | 653 // Set array length to 0. |
| 637 array->SetElementsLength(Smi::FromInt(0)); | 654 array->SetElementsLength(Smi::FromInt(0)); |
| 638 CHECK_EQ(Smi::FromInt(0), array->length()); | 655 CHECK_EQ(Smi::FromInt(0), array->length()); |
| 639 CHECK(array->HasFastElements()); // Must be in fast mode. | 656 CHECK(array->HasFastElements()); // Must be in fast mode. |
| 640 | 657 |
| 641 // array[length] = name. | 658 // array[length] = name. |
| 642 array->SetElement(0, name); | 659 array->SetElement(0, *name); |
| 643 CHECK_EQ(Smi::FromInt(1), array->length()); | 660 CHECK_EQ(Smi::FromInt(1), array->length()); |
| 644 CHECK_EQ(array->GetElement(0), name); | 661 CHECK_EQ(array->GetElement(0), *name); |
| 645 | 662 |
| 646 // Set array length with larger than smi value. | 663 // Set array length with larger than smi value. |
| 647 Object* length = | 664 Handle<Object> length = |
| 648 Heap::NumberFromUint32(static_cast<uint32_t>(Smi::kMaxValue) + 1); | 665 Factory::NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1); |
| 649 array->SetElementsLength(length); | 666 array->SetElementsLength(*length); |
| 650 | 667 |
| 651 uint32_t int_length = 0; | 668 uint32_t int_length = 0; |
| 652 CHECK(Array::IndexFromObject(length, &int_length)); | 669 CHECK(Array::IndexFromObject(*length, &int_length)); |
| 653 CHECK_EQ(length, array->length()); | 670 CHECK_EQ(*length, array->length()); |
| 654 CHECK(array->HasDictionaryElements()); // Must be in slow mode. | 671 CHECK(array->HasDictionaryElements()); // Must be in slow mode. |
| 655 | 672 |
| 656 // array[length] = name. | 673 // array[length] = name. |
| 657 array->SetElement(int_length, name); | 674 array->SetElement(int_length, *name); |
| 658 uint32_t new_int_length = 0; | 675 uint32_t new_int_length = 0; |
| 659 CHECK(Array::IndexFromObject(array->length(), &new_int_length)); | 676 CHECK(Array::IndexFromObject(array->length(), &new_int_length)); |
| 660 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); | 677 CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); |
| 661 CHECK_EQ(array->GetElement(int_length), name); | 678 CHECK_EQ(array->GetElement(int_length), *name); |
| 662 CHECK_EQ(array->GetElement(0), name); | 679 CHECK_EQ(array->GetElement(0), *name); |
| 663 } | 680 } |
| 664 | 681 |
| 665 | 682 |
| 666 TEST(JSObjectCopy) { | 683 TEST(JSObjectCopy) { |
| 667 InitializeVM(); | 684 InitializeVM(); |
| 668 | 685 |
| 669 v8::HandleScope sc; | 686 v8::HandleScope sc; |
| 670 String* name = String::cast(Heap::Object_symbol()); | 687 String* object_symbol = String::cast(Heap::Object_symbol()); |
| 671 JSFunction* constructor = | 688 JSFunction* object_function = |
| 672 JSFunction::cast(Top::context()->global()->GetProperty(name)); | 689 JSFunction::cast(Top::context()->global()->GetProperty(object_symbol)); |
| 673 JSObject* obj = JSObject::cast(Heap::AllocateJSObject(constructor)); | 690 Handle<JSFunction> constructor(object_function); |
| 674 String* first = String::cast(Heap::LookupAsciiSymbol("first")); | 691 Handle<JSObject> obj = Factory::NewJSObject(constructor); |
| 675 String* second = String::cast(Heap::LookupAsciiSymbol("second")); | 692 Handle<String> first = Factory::LookupAsciiSymbol("first"); |
| 693 Handle<String> second = Factory::LookupAsciiSymbol("second"); |
| 676 | 694 |
| 677 obj->SetProperty(first, Smi::FromInt(1), NONE); | 695 obj->SetProperty(*first, Smi::FromInt(1), NONE); |
| 678 obj->SetProperty(second, Smi::FromInt(2), NONE); | 696 obj->SetProperty(*second, Smi::FromInt(2), NONE); |
| 679 | 697 |
| 680 obj->SetElement(0, first); | 698 obj->SetElement(0, *first); |
| 681 obj->SetElement(1, second); | 699 obj->SetElement(1, *second); |
| 682 | 700 |
| 683 // Make the clone. | 701 // Make the clone. |
| 684 JSObject* clone = JSObject::cast(Heap::CopyJSObject(obj)); | 702 Handle<JSObject> clone = Copy(obj); |
| 685 CHECK(clone != obj); | 703 CHECK(!clone.is_identical_to(obj)); |
| 686 | 704 |
| 687 CHECK_EQ(obj->GetElement(0), clone->GetElement(0)); | 705 CHECK_EQ(obj->GetElement(0), clone->GetElement(0)); |
| 688 CHECK_EQ(obj->GetElement(1), clone->GetElement(1)); | 706 CHECK_EQ(obj->GetElement(1), clone->GetElement(1)); |
| 689 | 707 |
| 690 CHECK_EQ(obj->GetProperty(first), clone->GetProperty(first)); | 708 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*first)); |
| 691 CHECK_EQ(obj->GetProperty(second), clone->GetProperty(second)); | 709 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*second)); |
| 692 | 710 |
| 693 // Flip the values. | 711 // Flip the values. |
| 694 clone->SetProperty(first, Smi::FromInt(2), NONE); | 712 clone->SetProperty(*first, Smi::FromInt(2), NONE); |
| 695 clone->SetProperty(second, Smi::FromInt(1), NONE); | 713 clone->SetProperty(*second, Smi::FromInt(1), NONE); |
| 696 | 714 |
| 697 clone->SetElement(0, second); | 715 clone->SetElement(0, *second); |
| 698 clone->SetElement(1, first); | 716 clone->SetElement(1, *first); |
| 699 | 717 |
| 700 CHECK_EQ(obj->GetElement(1), clone->GetElement(0)); | 718 CHECK_EQ(obj->GetElement(1), clone->GetElement(0)); |
| 701 CHECK_EQ(obj->GetElement(0), clone->GetElement(1)); | 719 CHECK_EQ(obj->GetElement(0), clone->GetElement(1)); |
| 702 | 720 |
| 703 CHECK_EQ(obj->GetProperty(second), clone->GetProperty(first)); | 721 CHECK_EQ(obj->GetProperty(*second), clone->GetProperty(*first)); |
| 704 CHECK_EQ(obj->GetProperty(first), clone->GetProperty(second)); | 722 CHECK_EQ(obj->GetProperty(*first), clone->GetProperty(*second)); |
| 705 } | 723 } |
| 706 | 724 |
| 707 | 725 |
| 708 TEST(StringAllocation) { | 726 TEST(StringAllocation) { |
| 709 InitializeVM(); | 727 InitializeVM(); |
| 710 | 728 |
| 711 | 729 |
| 712 const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 }; | 730 const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 }; |
| 713 for (int length = 0; length < 100; length++) { | 731 for (int length = 0; length < 100; length++) { |
| 714 v8::HandleScope scope; | 732 v8::HandleScope scope; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 objs[next_objs_index++] = | 802 objs[next_objs_index++] = |
| 785 Factory::NewStringFromAscii(CStrVector(str), TENURED); | 803 Factory::NewStringFromAscii(CStrVector(str), TENURED); |
| 786 delete[] str; | 804 delete[] str; |
| 787 | 805 |
| 788 // Add a Map object to look for. | 806 // Add a Map object to look for. |
| 789 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); | 807 objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map()); |
| 790 | 808 |
| 791 CHECK_EQ(objs_count, next_objs_index); | 809 CHECK_EQ(objs_count, next_objs_index); |
| 792 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); | 810 CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count)); |
| 793 } | 811 } |
| OLD | NEW |