| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); | 131 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); |
| 132 Object* holder = NULL; | 132 Object* holder = NULL; |
| 133 Context* global_context = Top::context()->global_context(); | 133 Context* global_context = Top::context()->global_context(); |
| 134 if (IsString()) { | 134 if (IsString()) { |
| 135 holder = global_context->string_function()->instance_prototype(); | 135 holder = global_context->string_function()->instance_prototype(); |
| 136 } else if (IsNumber()) { | 136 } else if (IsNumber()) { |
| 137 holder = global_context->number_function()->instance_prototype(); | 137 holder = global_context->number_function()->instance_prototype(); |
| 138 } else if (IsBoolean()) { | 138 } else if (IsBoolean()) { |
| 139 holder = global_context->boolean_function()->instance_prototype(); | 139 holder = global_context->boolean_function()->instance_prototype(); |
| 140 } | 140 } |
| 141 ASSERT(holder != NULL); // cannot handle null or undefined. | 141 ASSERT(holder != NULL); // Cannot handle null or undefined. |
| 142 JSObject::cast(holder)->Lookup(name, result); | 142 JSObject::cast(holder)->Lookup(name, result); |
| 143 } | 143 } |
| 144 | 144 |
| 145 | 145 |
| 146 Object* Object::GetPropertyWithReceiver(Object* receiver, | 146 Object* Object::GetPropertyWithReceiver(Object* receiver, |
| 147 String* name, | 147 String* name, |
| 148 PropertyAttributes* attributes) { | 148 PropertyAttributes* attributes) { |
| 149 LookupResult result; | 149 LookupResult result; |
| 150 Lookup(name, &result); | 150 Lookup(name, &result); |
| 151 Object* value = GetProperty(receiver, &result, name, attributes); | 151 Object* value = GetProperty(receiver, &result, name, attributes); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 Handle<JSObject> this_handle(this); | 392 Handle<JSObject> this_handle(this); |
| 393 Handle<String> name_handle(name); | 393 Handle<String> name_handle(name); |
| 394 bool pending_exception; | 394 bool pending_exception; |
| 395 LoadLazy(Handle<JSObject>(JSObject::cast(result->GetLazyValue())), | 395 LoadLazy(Handle<JSObject>(JSObject::cast(result->GetLazyValue())), |
| 396 &pending_exception); | 396 &pending_exception); |
| 397 if (pending_exception) return Failure::Exception(); | 397 if (pending_exception) return Failure::Exception(); |
| 398 return this_handle->DeleteProperty(*name_handle, mode); | 398 return this_handle->DeleteProperty(*name_handle, mode); |
| 399 } | 399 } |
| 400 | 400 |
| 401 | 401 |
| 402 Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
| 403 ASSERT(!HasFastProperties()); |
| 404 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 405 if (IsJSGlobalObject()) { |
| 406 value = JSGlobalPropertyCell::cast(value)->value(); |
| 407 } |
| 408 ASSERT(!value->IsJSGlobalPropertyCell()); |
| 409 return value; |
| 410 } |
| 411 |
| 412 |
| 413 Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) { |
| 414 ASSERT(!HasFastProperties()); |
| 415 if (IsJSGlobalObject()) { |
| 416 JSGlobalPropertyCell* cell = |
| 417 JSGlobalPropertyCell::cast( |
| 418 property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
| 419 cell->set_value(value); |
| 420 } else { |
| 421 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 422 } |
| 423 return value; |
| 424 } |
| 425 |
| 426 |
| 427 Object* JSObject::SetNormalizedProperty(String* name, |
| 428 Object* value, |
| 429 PropertyDetails details) { |
| 430 ASSERT(!HasFastProperties()); |
| 431 int entry = property_dictionary()->FindStringEntry(name); |
| 432 if (entry == Dictionary::kNotFound) { |
| 433 Object* store_value = value; |
| 434 if (IsJSGlobalObject()) { |
| 435 store_value = Heap::AllocateJSGlobalPropertyCell(value); |
| 436 if (store_value->IsFailure()) return store_value; |
| 437 } |
| 438 Object* dict = |
| 439 property_dictionary()->AddStringEntry(name, store_value, details); |
| 440 if (dict->IsFailure()) return dict; |
| 441 set_properties(Dictionary::cast(dict)); |
| 442 return value; |
| 443 } |
| 444 // Preserve enumeration index. |
| 445 details = PropertyDetails(details.attributes(), |
| 446 details.type(), |
| 447 property_dictionary()->DetailsAt(entry).index()); |
| 448 if (IsJSGlobalObject()) { |
| 449 JSGlobalPropertyCell* cell = |
| 450 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); |
| 451 cell->set_value(value); |
| 452 // Please note we have to update the property details. |
| 453 property_dictionary()->DetailsAtPut(entry, details); |
| 454 } else { |
| 455 property_dictionary()->SetStringEntry(entry, name, value, details); |
| 456 } |
| 457 return value; |
| 458 } |
| 459 |
| 460 |
| 461 Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
| 462 ASSERT(!HasFastProperties()); |
| 463 Dictionary* dictionary = property_dictionary(); |
| 464 int entry = dictionary->FindStringEntry(name); |
| 465 if (entry != Dictionary::kNotFound) { |
| 466 // If we have a global object set the cell to the hole. |
| 467 if (IsJSGlobalObject()) { |
| 468 PropertyDetails details = dictionary->DetailsAt(entry); |
| 469 if (details.IsDontDelete() && mode != FORCE_DELETION) { |
| 470 return Heap::false_value(); |
| 471 } |
| 472 JSGlobalPropertyCell* cell = |
| 473 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
| 474 cell->set_value(Heap::the_hole_value()); |
| 475 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 476 } else { |
| 477 return dictionary->DeleteProperty(entry, mode); |
| 478 } |
| 479 } |
| 480 return Heap::true_value(); |
| 481 } |
| 482 |
| 483 |
| 402 Object* Object::GetProperty(Object* receiver, | 484 Object* Object::GetProperty(Object* receiver, |
| 403 LookupResult* result, | 485 LookupResult* result, |
| 404 String* name, | 486 String* name, |
| 405 PropertyAttributes* attributes) { | 487 PropertyAttributes* attributes) { |
| 406 // Make sure that the top context does not change when doing | 488 // Make sure that the top context does not change when doing |
| 407 // callbacks or interceptor calls. | 489 // callbacks or interceptor calls. |
| 408 AssertNoContextChange ncc; | 490 AssertNoContextChange ncc; |
| 409 | 491 |
| 410 // Traverse the prototype chain from the current object (this) to | 492 // Traverse the prototype chain from the current object (this) to |
| 411 // the holder and check for access rights. This avoid traversing the | 493 // the holder and check for access rights. This avoid traversing the |
| (...skipping 30 matching lines...) Expand all Loading... |
| 442 if (!result->IsLoaded()) { | 524 if (!result->IsLoaded()) { |
| 443 return JSObject::cast(this)->GetLazyProperty(receiver, | 525 return JSObject::cast(this)->GetLazyProperty(receiver, |
| 444 result, | 526 result, |
| 445 name, | 527 name, |
| 446 attributes); | 528 attributes); |
| 447 } | 529 } |
| 448 Object* value; | 530 Object* value; |
| 449 JSObject* holder = result->holder(); | 531 JSObject* holder = result->holder(); |
| 450 switch (result->type()) { | 532 switch (result->type()) { |
| 451 case NORMAL: | 533 case NORMAL: |
| 452 value = | 534 value = holder->GetNormalizedProperty(result); |
| 453 holder->property_dictionary()->ValueAt(result->GetDictionaryEntry()); | |
| 454 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 535 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 455 return value->IsTheHole() ? Heap::undefined_value() : value; | 536 return value->IsTheHole() ? Heap::undefined_value() : value; |
| 456 case FIELD: | 537 case FIELD: |
| 457 value = holder->FastPropertyAt(result->GetFieldIndex()); | 538 value = holder->FastPropertyAt(result->GetFieldIndex()); |
| 458 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 539 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 459 return value->IsTheHole() ? Heap::undefined_value() : value; | 540 return value->IsTheHole() ? Heap::undefined_value() : value; |
| 460 case CONSTANT_FUNCTION: | 541 case CONSTANT_FUNCTION: |
| 461 return result->GetConstantFunction(); | 542 return result->GetConstantFunction(); |
| 462 case CALLBACKS: | 543 case CALLBACKS: |
| 463 return GetPropertyWithCallback(receiver, | 544 return GetPropertyWithCallback(receiver, |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 break; | 1023 break; |
| 943 } | 1024 } |
| 944 case HEAP_NUMBER_TYPE: | 1025 case HEAP_NUMBER_TYPE: |
| 945 accumulator->Add("<Number: "); | 1026 accumulator->Add("<Number: "); |
| 946 HeapNumber::cast(this)->HeapNumberPrint(accumulator); | 1027 HeapNumber::cast(this)->HeapNumberPrint(accumulator); |
| 947 accumulator->Put('>'); | 1028 accumulator->Put('>'); |
| 948 break; | 1029 break; |
| 949 case PROXY_TYPE: | 1030 case PROXY_TYPE: |
| 950 accumulator->Add("<Proxy>"); | 1031 accumulator->Add("<Proxy>"); |
| 951 break; | 1032 break; |
| 1033 case JS_GLOBAL_PROPERTY_CELL_TYPE: |
| 1034 accumulator->Add("Cell for "); |
| 1035 JSGlobalPropertyCell::cast(this)->value()->ShortPrint(accumulator); |
| 1036 break; |
| 952 default: | 1037 default: |
| 953 accumulator->Add("<Other heap object (%d)>", map()->instance_type()); | 1038 accumulator->Add("<Other heap object (%d)>", map()->instance_type()); |
| 954 break; | 1039 break; |
| 955 } | 1040 } |
| 956 } | 1041 } |
| 957 | 1042 |
| 958 | 1043 |
| 959 int HeapObject::SlowSizeFromMap(Map* map) { | 1044 int HeapObject::SlowSizeFromMap(Map* map) { |
| 960 // Avoid calling functions such as FixedArray::cast during GC, which | 1045 // Avoid calling functions such as FixedArray::cast during GC, which |
| 961 // read map pointer of this object again. | 1046 // read map pointer of this object again. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 break; | 1120 break; |
| 1036 case PROXY_TYPE: | 1121 case PROXY_TYPE: |
| 1037 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); | 1122 reinterpret_cast<Proxy*>(this)->ProxyIterateBody(v); |
| 1038 break; | 1123 break; |
| 1039 case MAP_TYPE: | 1124 case MAP_TYPE: |
| 1040 reinterpret_cast<Map*>(this)->MapIterateBody(v); | 1125 reinterpret_cast<Map*>(this)->MapIterateBody(v); |
| 1041 break; | 1126 break; |
| 1042 case CODE_TYPE: | 1127 case CODE_TYPE: |
| 1043 reinterpret_cast<Code*>(this)->CodeIterateBody(v); | 1128 reinterpret_cast<Code*>(this)->CodeIterateBody(v); |
| 1044 break; | 1129 break; |
| 1130 case JS_GLOBAL_PROPERTY_CELL_TYPE: |
| 1131 reinterpret_cast<JSGlobalPropertyCell*>(this) |
| 1132 ->JSGlobalPropertyCellIterateBody(v); |
| 1133 break; |
| 1045 case HEAP_NUMBER_TYPE: | 1134 case HEAP_NUMBER_TYPE: |
| 1046 case FILLER_TYPE: | 1135 case FILLER_TYPE: |
| 1047 case BYTE_ARRAY_TYPE: | 1136 case BYTE_ARRAY_TYPE: |
| 1048 break; | 1137 break; |
| 1049 case SHARED_FUNCTION_INFO_TYPE: { | 1138 case SHARED_FUNCTION_INFO_TYPE: { |
| 1050 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this); | 1139 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this); |
| 1051 shared->SharedFunctionInfoIterateBody(v); | 1140 shared->SharedFunctionInfoIterateBody(v); |
| 1052 break; | 1141 break; |
| 1053 } | 1142 } |
| 1054 #define MAKE_STRUCT_CASE(NAME, Name, name) \ | 1143 #define MAKE_STRUCT_CASE(NAME, Name, name) \ |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1332 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1244 | 1333 |
| 1245 return function; | 1334 return function; |
| 1246 } | 1335 } |
| 1247 | 1336 |
| 1248 | 1337 |
| 1249 // Add property in slow mode | 1338 // Add property in slow mode |
| 1250 Object* JSObject::AddSlowProperty(String* name, | 1339 Object* JSObject::AddSlowProperty(String* name, |
| 1251 Object* value, | 1340 Object* value, |
| 1252 PropertyAttributes attributes) { | 1341 PropertyAttributes attributes) { |
| 1342 ASSERT(!HasFastProperties()); |
| 1343 Dictionary* dict = property_dictionary(); |
| 1344 Object* store_value = value; |
| 1345 if (IsJSGlobalObject()) { |
| 1346 // In case name is an orphaned property reuse the cell. |
| 1347 int entry = dict->FindStringEntry(name); |
| 1348 if (entry != Dictionary::kNotFound) { |
| 1349 store_value = dict->ValueAt(entry); |
| 1350 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1351 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1352 dict->SetStringEntry(entry, name, store_value, details); |
| 1353 return value; |
| 1354 } |
| 1355 store_value = Heap::AllocateJSGlobalPropertyCell(value); |
| 1356 if (store_value->IsFailure()) return store_value; |
| 1357 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1358 } |
| 1253 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1359 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1254 Object* result = property_dictionary()->AddStringEntry(name, value, details); | 1360 Object* result = dict->AddStringEntry(name, store_value, details); |
| 1255 if (result->IsFailure()) return result; | 1361 if (result->IsFailure()) return result; |
| 1256 if (property_dictionary() != result) { | 1362 if (dict != result) set_properties(Dictionary::cast(result)); |
| 1257 set_properties(Dictionary::cast(result)); | |
| 1258 } | |
| 1259 return value; | 1363 return value; |
| 1260 } | 1364 } |
| 1261 | 1365 |
| 1262 | 1366 |
| 1263 Object* JSObject::AddProperty(String* name, | 1367 Object* JSObject::AddProperty(String* name, |
| 1264 Object* value, | 1368 Object* value, |
| 1265 PropertyAttributes attributes) { | 1369 PropertyAttributes attributes) { |
| 1266 ASSERT(!IsJSGlobalProxy()); | 1370 ASSERT(!IsJSGlobalProxy()); |
| 1267 if (HasFastProperties()) { | 1371 if (HasFastProperties()) { |
| 1268 // Ensure the descriptor array does not get too big. | 1372 // Ensure the descriptor array does not get too big. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 Dictionary* dictionary = property_dictionary(); | 1408 Dictionary* dictionary = property_dictionary(); |
| 1305 int old_index = dictionary->FindStringEntry(name); | 1409 int old_index = dictionary->FindStringEntry(name); |
| 1306 int new_enumeration_index = 0; // 0 means "Use the next available index." | 1410 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| 1307 if (old_index != -1) { | 1411 if (old_index != -1) { |
| 1308 // All calls to ReplaceSlowProperty have had all transitions removed. | 1412 // All calls to ReplaceSlowProperty have had all transitions removed. |
| 1309 ASSERT(!dictionary->DetailsAt(old_index).IsTransition()); | 1413 ASSERT(!dictionary->DetailsAt(old_index).IsTransition()); |
| 1310 new_enumeration_index = dictionary->DetailsAt(old_index).index(); | 1414 new_enumeration_index = dictionary->DetailsAt(old_index).index(); |
| 1311 } | 1415 } |
| 1312 | 1416 |
| 1313 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); | 1417 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); |
| 1314 Object* result = | 1418 return SetNormalizedProperty(name, value, new_details); |
| 1315 dictionary->SetOrAddStringEntry(name, value, new_details); | |
| 1316 if (result->IsFailure()) return result; | |
| 1317 if (dictionary != result) { | |
| 1318 set_properties(Dictionary::cast(result)); | |
| 1319 } | |
| 1320 return value; | |
| 1321 } | 1419 } |
| 1322 | 1420 |
| 1323 Object* JSObject::ConvertDescriptorToFieldAndMapTransition( | 1421 Object* JSObject::ConvertDescriptorToFieldAndMapTransition( |
| 1324 String* name, | 1422 String* name, |
| 1325 Object* new_value, | 1423 Object* new_value, |
| 1326 PropertyAttributes attributes) { | 1424 PropertyAttributes attributes) { |
| 1327 Map* old_map = map(); | 1425 Map* old_map = map(); |
| 1328 Object* result = ConvertDescriptorToField(name, new_value, attributes); | 1426 Object* result = ConvertDescriptorToField(name, new_value, attributes); |
| 1329 if (result->IsFailure()) return result; | 1427 if (result->IsFailure()) return result; |
| 1330 // If we get to this point we have succeeded - do not return failure | 1428 // If we get to this point we have succeeded - do not return failure |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1543 } | 1641 } |
| 1544 | 1642 |
| 1545 | 1643 |
| 1546 Object* JSObject::LookupCallbackSetterInPrototypes(uint32_t index) { | 1644 Object* JSObject::LookupCallbackSetterInPrototypes(uint32_t index) { |
| 1547 for (Object* pt = GetPrototype(); | 1645 for (Object* pt = GetPrototype(); |
| 1548 pt != Heap::null_value(); | 1646 pt != Heap::null_value(); |
| 1549 pt = pt->GetPrototype()) { | 1647 pt = pt->GetPrototype()) { |
| 1550 if (JSObject::cast(pt)->HasFastElements()) continue; | 1648 if (JSObject::cast(pt)->HasFastElements()) continue; |
| 1551 Dictionary* dictionary = JSObject::cast(pt)->element_dictionary(); | 1649 Dictionary* dictionary = JSObject::cast(pt)->element_dictionary(); |
| 1552 int entry = dictionary->FindNumberEntry(index); | 1650 int entry = dictionary->FindNumberEntry(index); |
| 1553 if (entry != -1) { | 1651 if (entry != Dictionary::kNotFound) { |
| 1554 Object* element = dictionary->ValueAt(entry); | 1652 Object* element = dictionary->ValueAt(entry); |
| 1555 PropertyDetails details = dictionary->DetailsAt(entry); | 1653 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1556 if (details.type() == CALLBACKS) { | 1654 if (details.type() == CALLBACKS) { |
| 1557 // Only accessors allowed as elements. | 1655 // Only accessors allowed as elements. |
| 1558 return FixedArray::cast(element)->get(kSetterIndex); | 1656 return FixedArray::cast(element)->get(kSetterIndex); |
| 1559 } | 1657 } |
| 1560 } | 1658 } |
| 1561 } | 1659 } |
| 1562 return Heap::undefined_value(); | 1660 return Heap::undefined_value(); |
| 1563 } | 1661 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1594 // Disallow caching for uninitialized constants. These can only | 1692 // Disallow caching for uninitialized constants. These can only |
| 1595 // occur as fields. | 1693 // occur as fields. |
| 1596 if (result->IsReadOnly() && result->type() == FIELD && | 1694 if (result->IsReadOnly() && result->type() == FIELD && |
| 1597 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { | 1695 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { |
| 1598 result->DisallowCaching(); | 1696 result->DisallowCaching(); |
| 1599 } | 1697 } |
| 1600 return; | 1698 return; |
| 1601 } | 1699 } |
| 1602 } else { | 1700 } else { |
| 1603 int entry = property_dictionary()->FindStringEntry(name); | 1701 int entry = property_dictionary()->FindStringEntry(name); |
| 1604 if (entry != DescriptorArray::kNotFound) { | 1702 if (entry != Dictionary::kNotFound) { |
| 1605 // Make sure to disallow caching for uninitialized constants | 1703 // Make sure to disallow caching for uninitialized constants |
| 1606 // found in the dictionary-mode objects. | 1704 // found in the dictionary-mode objects. |
| 1607 if (property_dictionary()->ValueAt(entry)->IsTheHole()) { | 1705 Object* value = property_dictionary()->ValueAt(entry); |
| 1706 if (IsJSGlobalObject()) { |
| 1707 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
| 1708 if (d.IsDeleted()) { |
| 1709 result->NotFound(); |
| 1710 return; |
| 1711 } |
| 1712 value = JSGlobalPropertyCell::cast(value)->value(); |
| 1713 ASSERT(result->IsLoaded()); |
| 1714 } |
| 1715 if (value->IsTheHole()) { |
| 1608 result->DisallowCaching(); | 1716 result->DisallowCaching(); |
| 1609 } | 1717 } |
| 1610 result->DictionaryResult(this, entry); | 1718 result->DictionaryResult(this, entry); |
| 1611 return; | 1719 return; |
| 1612 } | 1720 } |
| 1613 // Slow case object skipped during lookup. Do not use inline caching. | 1721 // Slow case object skipped during lookup. Do not use inline caching. |
| 1614 result->DisallowCaching(); | 1722 result->DisallowCaching(); |
| 1615 } | 1723 } |
| 1616 result->NotFound(); | 1724 result->NotFound(); |
| 1617 } | 1725 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1729 return AddProperty(name, value, attributes); | 1837 return AddProperty(name, value, attributes); |
| 1730 } | 1838 } |
| 1731 if (!result->IsLoaded()) { | 1839 if (!result->IsLoaded()) { |
| 1732 return SetLazyProperty(result, name, value, attributes); | 1840 return SetLazyProperty(result, name, value, attributes); |
| 1733 } | 1841 } |
| 1734 if (result->IsReadOnly() && result->IsProperty()) return value; | 1842 if (result->IsReadOnly() && result->IsProperty()) return value; |
| 1735 // This is a real property that is not read-only, or it is a | 1843 // This is a real property that is not read-only, or it is a |
| 1736 // transition or null descriptor and there are no setters in the prototypes. | 1844 // transition or null descriptor and there are no setters in the prototypes. |
| 1737 switch (result->type()) { | 1845 switch (result->type()) { |
| 1738 case NORMAL: | 1846 case NORMAL: |
| 1739 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 1847 return SetNormalizedProperty(result, value); |
| 1740 return value; | |
| 1741 case FIELD: | 1848 case FIELD: |
| 1742 return FastPropertyAtPut(result->GetFieldIndex(), value); | 1849 return FastPropertyAtPut(result->GetFieldIndex(), value); |
| 1743 case MAP_TRANSITION: | 1850 case MAP_TRANSITION: |
| 1744 if (attributes == result->GetAttributes()) { | 1851 if (attributes == result->GetAttributes()) { |
| 1745 // Only use map transition if the attributes match. | 1852 // Only use map transition if the attributes match. |
| 1746 return AddFastPropertyUsingMap(result->GetTransitionMap(), | 1853 return AddFastPropertyUsingMap(result->GetTransitionMap(), |
| 1747 name, | 1854 name, |
| 1748 value); | 1855 value); |
| 1749 } | 1856 } |
| 1750 return ConvertDescriptorToField(name, value, attributes); | 1857 return ConvertDescriptorToField(name, value, attributes); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1812 // Check for accessor in prototype chain removed here in clone. | 1919 // Check for accessor in prototype chain removed here in clone. |
| 1813 if (result->IsNotFound()) { | 1920 if (result->IsNotFound()) { |
| 1814 return AddProperty(name, value, attributes); | 1921 return AddProperty(name, value, attributes); |
| 1815 } | 1922 } |
| 1816 if (!result->IsLoaded()) { | 1923 if (!result->IsLoaded()) { |
| 1817 return SetLazyProperty(result, name, value, attributes); | 1924 return SetLazyProperty(result, name, value, attributes); |
| 1818 } | 1925 } |
| 1819 // Check of IsReadOnly removed from here in clone. | 1926 // Check of IsReadOnly removed from here in clone. |
| 1820 switch (result->type()) { | 1927 switch (result->type()) { |
| 1821 case NORMAL: | 1928 case NORMAL: |
| 1822 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 1929 return SetNormalizedProperty(result, value); |
| 1823 return value; | |
| 1824 case FIELD: | 1930 case FIELD: |
| 1825 return FastPropertyAtPut(result->GetFieldIndex(), value); | 1931 return FastPropertyAtPut(result->GetFieldIndex(), value); |
| 1826 case MAP_TRANSITION: | 1932 case MAP_TRANSITION: |
| 1827 if (attributes == result->GetAttributes()) { | 1933 if (attributes == result->GetAttributes()) { |
| 1828 // Only use map transition if the attributes match. | 1934 // Only use map transition if the attributes match. |
| 1829 return AddFastPropertyUsingMap(result->GetTransitionMap(), | 1935 return AddFastPropertyUsingMap(result->GetTransitionMap(), |
| 1830 name, | 1936 name, |
| 1831 value); | 1937 value); |
| 1832 } | 1938 } |
| 1833 return ConvertDescriptorToField(name, value, attributes); | 1939 return ConvertDescriptorToField(name, value, attributes); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 | 2107 |
| 2002 for (DescriptorReader r(map()->instance_descriptors()); | 2108 for (DescriptorReader r(map()->instance_descriptors()); |
| 2003 !r.eos(); | 2109 !r.eos(); |
| 2004 r.advance()) { | 2110 r.advance()) { |
| 2005 PropertyDetails details = r.GetDetails(); | 2111 PropertyDetails details = r.GetDetails(); |
| 2006 switch (details.type()) { | 2112 switch (details.type()) { |
| 2007 case CONSTANT_FUNCTION: { | 2113 case CONSTANT_FUNCTION: { |
| 2008 PropertyDetails d = | 2114 PropertyDetails d = |
| 2009 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2115 PropertyDetails(details.attributes(), NORMAL, details.index()); |
| 2010 Object* value = r.GetConstantFunction(); | 2116 Object* value = r.GetConstantFunction(); |
| 2117 if (IsJSGlobalObject()) { |
| 2118 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2119 if (value->IsFailure()) return value; |
| 2120 } |
| 2011 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); | 2121 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
| 2012 if (result->IsFailure()) return result; | 2122 if (result->IsFailure()) return result; |
| 2013 dictionary = Dictionary::cast(result); | 2123 dictionary = Dictionary::cast(result); |
| 2014 break; | 2124 break; |
| 2015 } | 2125 } |
| 2016 case FIELD: { | 2126 case FIELD: { |
| 2017 PropertyDetails d = | 2127 PropertyDetails d = |
| 2018 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2128 PropertyDetails(details.attributes(), NORMAL, details.index()); |
| 2019 Object* value = FastPropertyAt(r.GetFieldIndex()); | 2129 Object* value = FastPropertyAt(r.GetFieldIndex()); |
| 2130 if (IsJSGlobalObject()) { |
| 2131 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2132 if (value->IsFailure()) return value; |
| 2133 } |
| 2020 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); | 2134 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
| 2021 if (result->IsFailure()) return result; | 2135 if (result->IsFailure()) return result; |
| 2022 dictionary = Dictionary::cast(result); | 2136 dictionary = Dictionary::cast(result); |
| 2023 break; | 2137 break; |
| 2024 } | 2138 } |
| 2025 case CALLBACKS: { | 2139 case CALLBACKS: { |
| 2026 PropertyDetails d = | 2140 PropertyDetails d = |
| 2027 PropertyDetails(details.attributes(), CALLBACKS, details.index()); | 2141 PropertyDetails(details.attributes(), CALLBACKS, details.index()); |
| 2028 Object* value = r.GetCallbacksObject(); | 2142 Object* value = r.GetCallbacksObject(); |
| 2143 if (IsJSGlobalObject()) { |
| 2144 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2145 if (value->IsFailure()) return value; |
| 2146 } |
| 2029 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); | 2147 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
| 2030 if (result->IsFailure()) return result; | 2148 if (result->IsFailure()) return result; |
| 2031 dictionary = Dictionary::cast(result); | 2149 dictionary = Dictionary::cast(result); |
| 2032 break; | 2150 break; |
| 2033 } | 2151 } |
| 2034 case MAP_TRANSITION: | 2152 case MAP_TRANSITION: |
| 2035 case CONSTANT_TRANSITION: | 2153 case CONSTANT_TRANSITION: |
| 2036 case NULL_DESCRIPTOR: | 2154 case NULL_DESCRIPTOR: |
| 2037 case INTERCEPTOR: | 2155 case INTERCEPTOR: |
| 2038 break; | 2156 break; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 PrintF("Object properties have been normalized:\n"); | 2196 PrintF("Object properties have been normalized:\n"); |
| 2079 Print(); | 2197 Print(); |
| 2080 } | 2198 } |
| 2081 #endif | 2199 #endif |
| 2082 return this; | 2200 return this; |
| 2083 } | 2201 } |
| 2084 | 2202 |
| 2085 | 2203 |
| 2086 Object* JSObject::TransformToFastProperties(int unused_property_fields) { | 2204 Object* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 2087 if (HasFastProperties()) return this; | 2205 if (HasFastProperties()) return this; |
| 2206 ASSERT(!IsJSGlobalObject()); |
| 2088 return property_dictionary()-> | 2207 return property_dictionary()-> |
| 2089 TransformPropertiesToFastFor(this, unused_property_fields); | 2208 TransformPropertiesToFastFor(this, unused_property_fields); |
| 2090 } | 2209 } |
| 2091 | 2210 |
| 2092 | 2211 |
| 2093 Object* JSObject::NormalizeElements() { | 2212 Object* JSObject::NormalizeElements() { |
| 2094 if (!HasFastElements()) return this; | 2213 if (!HasFastElements()) return this; |
| 2095 | 2214 |
| 2096 // Get number of entries. | 2215 // Get number of entries. |
| 2097 FixedArray* array = FixedArray::cast(elements()); | 2216 FixedArray* array = FixedArray::cast(elements()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2132 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { | 2251 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { |
| 2133 // Check local property, ignore interceptor. | 2252 // Check local property, ignore interceptor. |
| 2134 LookupResult result; | 2253 LookupResult result; |
| 2135 LocalLookupRealNamedProperty(name, &result); | 2254 LocalLookupRealNamedProperty(name, &result); |
| 2136 if (!result.IsValid()) return Heap::true_value(); | 2255 if (!result.IsValid()) return Heap::true_value(); |
| 2137 | 2256 |
| 2138 // Normalize object if needed. | 2257 // Normalize object if needed. |
| 2139 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); | 2258 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2140 if (obj->IsFailure()) return obj; | 2259 if (obj->IsFailure()) return obj; |
| 2141 | 2260 |
| 2142 ASSERT(!HasFastProperties()); | 2261 return DeleteNormalizedProperty(name, mode); |
| 2143 // Attempt to remove the property from the property dictionary. | |
| 2144 Dictionary* dictionary = property_dictionary(); | |
| 2145 int entry = dictionary->FindStringEntry(name); | |
| 2146 if (entry != -1) return dictionary->DeleteProperty(entry, mode); | |
| 2147 return Heap::true_value(); | |
| 2148 } | 2262 } |
| 2149 | 2263 |
| 2150 | 2264 |
| 2151 Object* JSObject::DeletePropertyWithInterceptor(String* name) { | 2265 Object* JSObject::DeletePropertyWithInterceptor(String* name) { |
| 2152 HandleScope scope; | 2266 HandleScope scope; |
| 2153 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 2267 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 2154 Handle<String> name_handle(name); | 2268 Handle<String> name_handle(name); |
| 2155 Handle<JSObject> this_handle(this); | 2269 Handle<JSObject> this_handle(this); |
| 2156 if (!interceptor->deleter()->IsUndefined()) { | 2270 if (!interceptor->deleter()->IsUndefined()) { |
| 2157 v8::NamedPropertyDeleter deleter = | 2271 v8::NamedPropertyDeleter deleter = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2187 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2301 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2188 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2302 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2189 if (index < length) { | 2303 if (index < length) { |
| 2190 FixedArray::cast(elements())->set_the_hole(index); | 2304 FixedArray::cast(elements())->set_the_hole(index); |
| 2191 } | 2305 } |
| 2192 return Heap::true_value(); | 2306 return Heap::true_value(); |
| 2193 } | 2307 } |
| 2194 ASSERT(!HasFastElements()); | 2308 ASSERT(!HasFastElements()); |
| 2195 Dictionary* dictionary = element_dictionary(); | 2309 Dictionary* dictionary = element_dictionary(); |
| 2196 int entry = dictionary->FindNumberEntry(index); | 2310 int entry = dictionary->FindNumberEntry(index); |
| 2197 if (entry != -1) return dictionary->DeleteProperty(entry, mode); | 2311 if (entry != Dictionary::kNotFound) { |
| 2312 return dictionary->DeleteProperty(entry, mode); |
| 2313 } |
| 2198 return Heap::true_value(); | 2314 return Heap::true_value(); |
| 2199 } | 2315 } |
| 2200 | 2316 |
| 2201 | 2317 |
| 2202 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2318 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
| 2203 // Make sure that the top context does not change when doing | 2319 // Make sure that the top context does not change when doing |
| 2204 // callbacks or interceptor calls. | 2320 // callbacks or interceptor calls. |
| 2205 AssertNoContextChange ncc; | 2321 AssertNoContextChange ncc; |
| 2206 HandleScope scope; | 2322 HandleScope scope; |
| 2207 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 2323 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2259 uint32_t length = IsJSArray() ? | 2375 uint32_t length = IsJSArray() ? |
| 2260 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2376 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2261 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2377 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2262 if (index < length) { | 2378 if (index < length) { |
| 2263 FixedArray::cast(elements())->set_the_hole(index); | 2379 FixedArray::cast(elements())->set_the_hole(index); |
| 2264 } | 2380 } |
| 2265 return Heap::true_value(); | 2381 return Heap::true_value(); |
| 2266 } else { | 2382 } else { |
| 2267 Dictionary* dictionary = element_dictionary(); | 2383 Dictionary* dictionary = element_dictionary(); |
| 2268 int entry = dictionary->FindNumberEntry(index); | 2384 int entry = dictionary->FindNumberEntry(index); |
| 2269 if (entry != -1) return dictionary->DeleteProperty(entry, mode); | 2385 if (entry != Dictionary::kNotFound) { |
| 2386 return dictionary->DeleteProperty(entry, mode); |
| 2387 } |
| 2270 } | 2388 } |
| 2271 return Heap::true_value(); | 2389 return Heap::true_value(); |
| 2272 } | 2390 } |
| 2273 | 2391 |
| 2274 | 2392 |
| 2275 Object* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 2393 Object* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
| 2276 // ECMA-262, 3rd, 8.6.2.5 | 2394 // ECMA-262, 3rd, 8.6.2.5 |
| 2277 ASSERT(name->IsString()); | 2395 ASSERT(name->IsString()); |
| 2278 | 2396 |
| 2279 // Check access rights if needed. | 2397 // Check access rights if needed. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2311 } | 2429 } |
| 2312 if (!result.IsLoaded()) { | 2430 if (!result.IsLoaded()) { |
| 2313 return JSObject::cast(this)->DeleteLazyProperty(&result, | 2431 return JSObject::cast(this)->DeleteLazyProperty(&result, |
| 2314 name, | 2432 name, |
| 2315 mode); | 2433 mode); |
| 2316 } | 2434 } |
| 2317 // Normalize object if needed. | 2435 // Normalize object if needed. |
| 2318 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); | 2436 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2319 if (obj->IsFailure()) return obj; | 2437 if (obj->IsFailure()) return obj; |
| 2320 // Make sure the properties are normalized before removing the entry. | 2438 // Make sure the properties are normalized before removing the entry. |
| 2321 Dictionary* dictionary = property_dictionary(); | 2439 return DeleteNormalizedProperty(name, mode); |
| 2322 int entry = dictionary->FindStringEntry(name); | |
| 2323 if (entry != -1) return dictionary->DeleteProperty(entry, mode); | |
| 2324 return Heap::true_value(); | |
| 2325 } | 2440 } |
| 2326 } | 2441 } |
| 2327 | 2442 |
| 2328 | 2443 |
| 2329 // Check whether this object references another object. | 2444 // Check whether this object references another object. |
| 2330 bool JSObject::ReferencesObject(Object* obj) { | 2445 bool JSObject::ReferencesObject(Object* obj) { |
| 2331 AssertNoAllocation no_alloc; | 2446 AssertNoAllocation no_alloc; |
| 2332 | 2447 |
| 2333 // Is the object the constructor for this object? | 2448 // Is the object the constructor for this object? |
| 2334 if (map()->constructor() == obj) { | 2449 if (map()->constructor() == obj) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2567 | 2682 |
| 2568 uint32_t index; | 2683 uint32_t index; |
| 2569 bool is_element = name->AsArrayIndex(&index); | 2684 bool is_element = name->AsArrayIndex(&index); |
| 2570 if (is_element && IsJSArray()) return Heap::undefined_value(); | 2685 if (is_element && IsJSArray()) return Heap::undefined_value(); |
| 2571 | 2686 |
| 2572 if (is_element) { | 2687 if (is_element) { |
| 2573 // Lookup the index. | 2688 // Lookup the index. |
| 2574 if (!HasFastElements()) { | 2689 if (!HasFastElements()) { |
| 2575 Dictionary* dictionary = element_dictionary(); | 2690 Dictionary* dictionary = element_dictionary(); |
| 2576 int entry = dictionary->FindNumberEntry(index); | 2691 int entry = dictionary->FindNumberEntry(index); |
| 2577 if (entry != -1) { | 2692 if (entry != Dictionary::kNotFound) { |
| 2578 Object* result = dictionary->ValueAt(entry); | 2693 Object* result = dictionary->ValueAt(entry); |
| 2579 PropertyDetails details = dictionary->DetailsAt(entry); | 2694 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2580 if (details.IsReadOnly()) return Heap::undefined_value(); | 2695 if (details.IsReadOnly()) return Heap::undefined_value(); |
| 2581 if (details.type() == CALLBACKS) { | 2696 if (details.type() == CALLBACKS) { |
| 2582 // Only accessors allowed as elements. | 2697 // Only accessors allowed as elements. |
| 2583 ASSERT(result->IsFixedArray()); | 2698 ASSERT(result->IsFixedArray()); |
| 2584 return result; | 2699 return result; |
| 2585 } | 2700 } |
| 2586 } | 2701 } |
| 2587 } | 2702 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2617 Dictionary* elements = Dictionary::cast(dict); | 2732 Dictionary* elements = Dictionary::cast(dict); |
| 2618 elements->set_requires_slow_elements(); | 2733 elements->set_requires_slow_elements(); |
| 2619 // Set the potential new dictionary on the object. | 2734 // Set the potential new dictionary on the object. |
| 2620 set_elements(Dictionary::cast(dict)); | 2735 set_elements(Dictionary::cast(dict)); |
| 2621 } else { | 2736 } else { |
| 2622 // Normalize object to make this operation simple. | 2737 // Normalize object to make this operation simple. |
| 2623 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); | 2738 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2624 if (ok->IsFailure()) return ok; | 2739 if (ok->IsFailure()) return ok; |
| 2625 | 2740 |
| 2626 // Update the dictionary with the new CALLBACKS property. | 2741 // Update the dictionary with the new CALLBACKS property. |
| 2627 Object* dict = | 2742 return SetNormalizedProperty(name, structure, details); |
| 2628 property_dictionary()->SetOrAddStringEntry(name, structure, details); | |
| 2629 if (dict->IsFailure()) return dict; | |
| 2630 | |
| 2631 // Set the potential new dictionary on the object. | |
| 2632 set_properties(Dictionary::cast(dict)); | |
| 2633 } | 2743 } |
| 2634 | 2744 |
| 2635 return structure; | 2745 return structure; |
| 2636 } | 2746 } |
| 2637 | 2747 |
| 2638 | 2748 |
| 2639 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, | 2749 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, |
| 2640 PropertyAttributes attributes) { | 2750 PropertyAttributes attributes) { |
| 2641 // Check access rights if needed. | 2751 // Check access rights if needed. |
| 2642 if (IsAccessCheckNeeded() && | 2752 if (IsAccessCheckNeeded() && |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2676 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; | 2786 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; |
| 2677 uint32_t index; | 2787 uint32_t index; |
| 2678 if (name->AsArrayIndex(&index)) { | 2788 if (name->AsArrayIndex(&index)) { |
| 2679 for (Object* obj = this; | 2789 for (Object* obj = this; |
| 2680 obj != Heap::null_value(); | 2790 obj != Heap::null_value(); |
| 2681 obj = JSObject::cast(obj)->GetPrototype()) { | 2791 obj = JSObject::cast(obj)->GetPrototype()) { |
| 2682 JSObject* jsObject = JSObject::cast(obj); | 2792 JSObject* jsObject = JSObject::cast(obj); |
| 2683 if (!jsObject->HasFastElements()) { | 2793 if (!jsObject->HasFastElements()) { |
| 2684 Dictionary* dictionary = jsObject->element_dictionary(); | 2794 Dictionary* dictionary = jsObject->element_dictionary(); |
| 2685 int entry = dictionary->FindNumberEntry(index); | 2795 int entry = dictionary->FindNumberEntry(index); |
| 2686 if (entry != -1) { | 2796 if (entry != Dictionary::kNotFound) { |
| 2687 Object* element = dictionary->ValueAt(entry); | 2797 Object* element = dictionary->ValueAt(entry); |
| 2688 PropertyDetails details = dictionary->DetailsAt(entry); | 2798 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2689 if (details.type() == CALLBACKS) { | 2799 if (details.type() == CALLBACKS) { |
| 2690 // Only accessors allowed as elements. | 2800 // Only accessors allowed as elements. |
| 2691 return FixedArray::cast(element)->get(accessor_index); | 2801 return FixedArray::cast(element)->get(accessor_index); |
| 2692 } | 2802 } |
| 2693 } | 2803 } |
| 2694 } | 2804 } |
| 2695 } | 2805 } |
| 2696 } else { | 2806 } else { |
| (...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3967 String::ReadBlockIntoBuffer(backing, rbb, &offset, max_chars); | 4077 String::ReadBlockIntoBuffer(backing, rbb, &offset, max_chars); |
| 3968 *offset_ptr = offset - start(); | 4078 *offset_ptr = offset - start(); |
| 3969 } | 4079 } |
| 3970 | 4080 |
| 3971 | 4081 |
| 3972 void ConsString::ConsStringIterateBody(ObjectVisitor* v) { | 4082 void ConsString::ConsStringIterateBody(ObjectVisitor* v) { |
| 3973 IteratePointers(v, kFirstOffset, kSecondOffset + kPointerSize); | 4083 IteratePointers(v, kFirstOffset, kSecondOffset + kPointerSize); |
| 3974 } | 4084 } |
| 3975 | 4085 |
| 3976 | 4086 |
| 4087 void JSGlobalPropertyCell::JSGlobalPropertyCellIterateBody(ObjectVisitor* v) { |
| 4088 IteratePointers(v, kValueOffset, kValueOffset + kPointerSize); |
| 4089 } |
| 4090 |
| 4091 |
| 3977 uint16_t ConsString::ConsStringGet(int index) { | 4092 uint16_t ConsString::ConsStringGet(int index) { |
| 3978 ASSERT(index >= 0 && index < this->length()); | 4093 ASSERT(index >= 0 && index < this->length()); |
| 3979 | 4094 |
| 3980 // Check for a flattened cons string | 4095 // Check for a flattened cons string |
| 3981 if (second()->length() == 0) { | 4096 if (second()->length() == 0) { |
| 3982 String* left = first(); | 4097 String* left = first(); |
| 3983 return left->Get(index); | 4098 return left->Get(index); |
| 3984 } | 4099 } |
| 3985 | 4100 |
| 3986 String* string = String::cast(this); | 4101 String* string = String::cast(this); |
| (...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4890 case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE"; | 5005 case MONOMORPHIC_PROTOTYPE_FAILURE: return "MONOMORPHIC_PROTOTYPE_FAILURE"; |
| 4891 case MEGAMORPHIC: return "MEGAMORPHIC"; | 5006 case MEGAMORPHIC: return "MEGAMORPHIC"; |
| 4892 case DEBUG_BREAK: return "DEBUG_BREAK"; | 5007 case DEBUG_BREAK: return "DEBUG_BREAK"; |
| 4893 case DEBUG_PREPARE_STEP_IN: return "DEBUG_PREPARE_STEP_IN"; | 5008 case DEBUG_PREPARE_STEP_IN: return "DEBUG_PREPARE_STEP_IN"; |
| 4894 } | 5009 } |
| 4895 UNREACHABLE(); | 5010 UNREACHABLE(); |
| 4896 return NULL; | 5011 return NULL; |
| 4897 } | 5012 } |
| 4898 | 5013 |
| 4899 | 5014 |
| 5015 const char* Code::PropertyType2String(PropertyType type) { |
| 5016 switch (type) { |
| 5017 case NORMAL: return "NORMAL"; |
| 5018 case FIELD: return "FIELD"; |
| 5019 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; |
| 5020 case CALLBACKS: return "CALLBACKS"; |
| 5021 case INTERCEPTOR: return "INTERCEPTOR"; |
| 5022 case MAP_TRANSITION: return "MAP_TRANSITION"; |
| 5023 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; |
| 5024 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; |
| 5025 } |
| 5026 UNREACHABLE(); |
| 5027 return NULL; |
| 5028 } |
| 5029 |
| 4900 void Code::Disassemble(const char* name) { | 5030 void Code::Disassemble(const char* name) { |
| 4901 PrintF("kind = %s\n", Kind2String(kind())); | 5031 PrintF("kind = %s\n", Kind2String(kind())); |
| 5032 if (is_inline_cache_stub()) { |
| 5033 PrintF("ic_state = %s\n", ICState2String(ic_state())); |
| 5034 PrintF("ic_in_loop = %d\n", ic_in_loop() == IN_LOOP); |
| 5035 if (ic_state() == MONOMORPHIC) { |
| 5036 PrintF("type = %s\n", PropertyType2String(type())); |
| 5037 } |
| 5038 } |
| 4902 if ((name != NULL) && (name[0] != '\0')) { | 5039 if ((name != NULL) && (name[0] != '\0')) { |
| 4903 PrintF("name = %s\n", name); | 5040 PrintF("name = %s\n", name); |
| 4904 } | 5041 } |
| 4905 | 5042 |
| 4906 PrintF("Instructions (size = %d)\n", instruction_size()); | 5043 PrintF("Instructions (size = %d)\n", instruction_size()); |
| 4907 Disassembler::Decode(NULL, this); | 5044 Disassembler::Decode(NULL, this); |
| 4908 PrintF("\n"); | 5045 PrintF("\n"); |
| 4909 | 5046 |
| 4910 PrintF("RelocInfo (size = %d)\n", relocation_size()); | 5047 PrintF("RelocInfo (size = %d)\n", relocation_size()); |
| 4911 for (RelocIterator it(this); !it.done(); it.next()) | 5048 for (RelocIterator it(this); !it.done(); it.next()) |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5088 if (HasFastElements()) { | 5225 if (HasFastElements()) { |
| 5089 uint32_t length = IsJSArray() ? | 5226 uint32_t length = IsJSArray() ? |
| 5090 static_cast<uint32_t>( | 5227 static_cast<uint32_t>( |
| 5091 Smi::cast(JSArray::cast(this)->length())->value()) : | 5228 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 5092 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 5229 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 5093 if ((index < length) && | 5230 if ((index < length) && |
| 5094 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 5231 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
| 5095 return true; | 5232 return true; |
| 5096 } | 5233 } |
| 5097 } else { | 5234 } else { |
| 5098 if (element_dictionary()->FindNumberEntry(index) != -1) return true; | 5235 if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) { |
| 5236 return true; |
| 5237 } |
| 5099 } | 5238 } |
| 5100 | 5239 |
| 5101 // Handle [] on String objects. | 5240 // Handle [] on String objects. |
| 5102 if (this->IsStringObjectWithCharacterAt(index)) return true; | 5241 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 5103 | 5242 |
| 5104 Object* pt = GetPrototype(); | 5243 Object* pt = GetPrototype(); |
| 5105 if (pt == Heap::null_value()) return false; | 5244 if (pt == Heap::null_value()) return false; |
| 5106 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 5245 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 5107 } | 5246 } |
| 5108 | 5247 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5163 if (this->IsStringObjectWithCharacterAt(index)) return true; | 5302 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 5164 | 5303 |
| 5165 if (HasFastElements()) { | 5304 if (HasFastElements()) { |
| 5166 uint32_t length = IsJSArray() ? | 5305 uint32_t length = IsJSArray() ? |
| 5167 static_cast<uint32_t>( | 5306 static_cast<uint32_t>( |
| 5168 Smi::cast(JSArray::cast(this)->length())->value()) : | 5307 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 5169 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 5308 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 5170 return (index < length) && | 5309 return (index < length) && |
| 5171 !FixedArray::cast(elements())->get(index)->IsTheHole(); | 5310 !FixedArray::cast(elements())->get(index)->IsTheHole(); |
| 5172 } else { | 5311 } else { |
| 5173 return element_dictionary()->FindNumberEntry(index) != -1; | 5312 return element_dictionary()->FindNumberEntry(index) |
| 5313 != Dictionary::kNotFound; |
| 5174 } | 5314 } |
| 5175 } | 5315 } |
| 5176 | 5316 |
| 5177 | 5317 |
| 5178 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 5318 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 5179 // Check access rights if needed. | 5319 // Check access rights if needed. |
| 5180 if (IsAccessCheckNeeded() && | 5320 if (IsAccessCheckNeeded() && |
| 5181 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 5321 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 5182 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 5322 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 5183 return false; | 5323 return false; |
| 5184 } | 5324 } |
| 5185 | 5325 |
| 5186 // Check for lookup interceptor | 5326 // Check for lookup interceptor |
| 5187 if (HasIndexedInterceptor()) { | 5327 if (HasIndexedInterceptor()) { |
| 5188 return HasElementWithInterceptor(receiver, index); | 5328 return HasElementWithInterceptor(receiver, index); |
| 5189 } | 5329 } |
| 5190 | 5330 |
| 5191 if (HasFastElements()) { | 5331 if (HasFastElements()) { |
| 5192 uint32_t length = IsJSArray() ? | 5332 uint32_t length = IsJSArray() ? |
| 5193 static_cast<uint32_t>( | 5333 static_cast<uint32_t>( |
| 5194 Smi::cast(JSArray::cast(this)->length())->value()) : | 5334 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 5195 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 5335 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 5196 if ((index < length) && | 5336 if ((index < length) && |
| 5197 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; | 5337 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; |
| 5198 } else { | 5338 } else { |
| 5199 if (element_dictionary()->FindNumberEntry(index) != -1) return true; | 5339 if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) { |
| 5340 return true; |
| 5341 } |
| 5200 } | 5342 } |
| 5201 | 5343 |
| 5202 // Handle [] on String objects. | 5344 // Handle [] on String objects. |
| 5203 if (this->IsStringObjectWithCharacterAt(index)) return true; | 5345 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 5204 | 5346 |
| 5205 Object* pt = GetPrototype(); | 5347 Object* pt = GetPrototype(); |
| 5206 if (pt == Heap::null_value()) return false; | 5348 if (pt == Heap::null_value()) return false; |
| 5207 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 5349 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 5208 } | 5350 } |
| 5209 | 5351 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5325 if (HasFastElements()) return SetFastElement(index, value); | 5467 if (HasFastElements()) return SetFastElement(index, value); |
| 5326 | 5468 |
| 5327 // Dictionary case. | 5469 // Dictionary case. |
| 5328 ASSERT(!HasFastElements()); | 5470 ASSERT(!HasFastElements()); |
| 5329 | 5471 |
| 5330 // Insert element in the dictionary. | 5472 // Insert element in the dictionary. |
| 5331 FixedArray* elms = FixedArray::cast(elements()); | 5473 FixedArray* elms = FixedArray::cast(elements()); |
| 5332 Dictionary* dictionary = Dictionary::cast(elms); | 5474 Dictionary* dictionary = Dictionary::cast(elms); |
| 5333 | 5475 |
| 5334 int entry = dictionary->FindNumberEntry(index); | 5476 int entry = dictionary->FindNumberEntry(index); |
| 5335 if (entry != -1) { | 5477 if (entry != Dictionary::kNotFound) { |
| 5336 Object* element = dictionary->ValueAt(entry); | 5478 Object* element = dictionary->ValueAt(entry); |
| 5337 PropertyDetails details = dictionary->DetailsAt(entry); | 5479 PropertyDetails details = dictionary->DetailsAt(entry); |
| 5338 if (details.type() == CALLBACKS) { | 5480 if (details.type() == CALLBACKS) { |
| 5339 // Only accessors allowed as elements. | 5481 // Only accessors allowed as elements. |
| 5340 FixedArray* structure = FixedArray::cast(element); | 5482 FixedArray* structure = FixedArray::cast(element); |
| 5341 if (structure->get(kSetterIndex)->IsJSFunction()) { | 5483 if (structure->get(kSetterIndex)->IsJSFunction()) { |
| 5342 JSFunction* setter = JSFunction::cast(structure->get(kSetterIndex)); | 5484 JSFunction* setter = JSFunction::cast(structure->get(kSetterIndex)); |
| 5343 return SetPropertyWithDefinedSetter(setter, value); | 5485 return SetPropertyWithDefinedSetter(setter, value); |
| 5344 } else { | 5486 } else { |
| 5345 Handle<Object> self(this); | 5487 Handle<Object> self(this); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5419 // JSArray::length cannot change. | 5561 // JSArray::length cannot change. |
| 5420 if (HasFastElements()) { | 5562 if (HasFastElements()) { |
| 5421 FixedArray* elms = FixedArray::cast(elements()); | 5563 FixedArray* elms = FixedArray::cast(elements()); |
| 5422 if (index < static_cast<uint32_t>(elms->length())) { | 5564 if (index < static_cast<uint32_t>(elms->length())) { |
| 5423 Object* value = elms->get(index); | 5565 Object* value = elms->get(index); |
| 5424 if (!value->IsTheHole()) return value; | 5566 if (!value->IsTheHole()) return value; |
| 5425 } | 5567 } |
| 5426 } else { | 5568 } else { |
| 5427 Dictionary* dictionary = element_dictionary(); | 5569 Dictionary* dictionary = element_dictionary(); |
| 5428 int entry = dictionary->FindNumberEntry(index); | 5570 int entry = dictionary->FindNumberEntry(index); |
| 5429 if (entry != -1) { | 5571 if (entry != Dictionary::kNotFound) { |
| 5430 Object* element = dictionary->ValueAt(entry); | 5572 Object* element = dictionary->ValueAt(entry); |
| 5431 PropertyDetails details = dictionary->DetailsAt(entry); | 5573 PropertyDetails details = dictionary->DetailsAt(entry); |
| 5432 if (details.type() == CALLBACKS) { | 5574 if (details.type() == CALLBACKS) { |
| 5433 // Only accessors allowed as elements. | 5575 // Only accessors allowed as elements. |
| 5434 FixedArray* structure = FixedArray::cast(element); | 5576 FixedArray* structure = FixedArray::cast(element); |
| 5435 Object* getter = structure->get(kGetterIndex); | 5577 Object* getter = structure->get(kGetterIndex); |
| 5436 if (getter->IsJSFunction()) { | 5578 if (getter->IsJSFunction()) { |
| 5437 return GetPropertyWithDefinedGetter(receiver, | 5579 return GetPropertyWithDefinedGetter(receiver, |
| 5438 JSFunction::cast(getter)); | 5580 JSFunction::cast(getter)); |
| 5439 } else { | 5581 } else { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5503 // JSArray::length cannot change. | 5645 // JSArray::length cannot change. |
| 5504 if (HasFastElements()) { | 5646 if (HasFastElements()) { |
| 5505 FixedArray* elms = FixedArray::cast(elements()); | 5647 FixedArray* elms = FixedArray::cast(elements()); |
| 5506 if (index < static_cast<uint32_t>(elms->length())) { | 5648 if (index < static_cast<uint32_t>(elms->length())) { |
| 5507 Object* value = elms->get(index); | 5649 Object* value = elms->get(index); |
| 5508 if (!value->IsTheHole()) return value; | 5650 if (!value->IsTheHole()) return value; |
| 5509 } | 5651 } |
| 5510 } else { | 5652 } else { |
| 5511 Dictionary* dictionary = element_dictionary(); | 5653 Dictionary* dictionary = element_dictionary(); |
| 5512 int entry = dictionary->FindNumberEntry(index); | 5654 int entry = dictionary->FindNumberEntry(index); |
| 5513 if (entry != -1) { | 5655 if (entry != Dictionary::kNotFound) { |
| 5514 Object* element = dictionary->ValueAt(entry); | 5656 Object* element = dictionary->ValueAt(entry); |
| 5515 PropertyDetails details = dictionary->DetailsAt(entry); | 5657 PropertyDetails details = dictionary->DetailsAt(entry); |
| 5516 if (details.type() == CALLBACKS) { | 5658 if (details.type() == CALLBACKS) { |
| 5517 // Only accessors allowed as elements. | 5659 // Only accessors allowed as elements. |
| 5518 FixedArray* structure = FixedArray::cast(element); | 5660 FixedArray* structure = FixedArray::cast(element); |
| 5519 Object* getter = structure->get(kGetterIndex); | 5661 Object* getter = structure->get(kGetterIndex); |
| 5520 if (getter->IsJSFunction()) { | 5662 if (getter->IsJSFunction()) { |
| 5521 return GetPropertyWithDefinedGetter(receiver, | 5663 return GetPropertyWithDefinedGetter(receiver, |
| 5522 JSFunction::cast(getter)); | 5664 JSFunction::cast(getter)); |
| 5523 } else { | 5665 } else { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5796 if (this->IsStringObjectWithCharacterAt(index)) return true; | 5938 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 5797 | 5939 |
| 5798 if (HasFastElements()) { | 5940 if (HasFastElements()) { |
| 5799 uint32_t length = IsJSArray() ? | 5941 uint32_t length = IsJSArray() ? |
| 5800 static_cast<uint32_t>( | 5942 static_cast<uint32_t>( |
| 5801 Smi::cast(JSArray::cast(this)->length())->value()) : | 5943 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 5802 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 5944 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 5803 return (index < length) && | 5945 return (index < length) && |
| 5804 !FixedArray::cast(elements())->get(index)->IsTheHole(); | 5946 !FixedArray::cast(elements())->get(index)->IsTheHole(); |
| 5805 } | 5947 } |
| 5806 return element_dictionary()->FindNumberEntry(index) != -1; | 5948 return element_dictionary()->FindNumberEntry(index) |
| 5949 != Dictionary::kNotFound; |
| 5807 } | 5950 } |
| 5808 | 5951 |
| 5809 | 5952 |
| 5810 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 5953 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 5811 // Check access rights if needed. | 5954 // Check access rights if needed. |
| 5812 if (IsAccessCheckNeeded() && | 5955 if (IsAccessCheckNeeded() && |
| 5813 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 5956 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 5814 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 5957 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 5815 return false; | 5958 return false; |
| 5816 } | 5959 } |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6321 HashTable::cast(obj)->SetCapacity(capacity); | 6464 HashTable::cast(obj)->SetCapacity(capacity); |
| 6322 } | 6465 } |
| 6323 return obj; | 6466 return obj; |
| 6324 } | 6467 } |
| 6325 | 6468 |
| 6326 | 6469 |
| 6327 // Find entry for key otherwise return -1. | 6470 // Find entry for key otherwise return -1. |
| 6328 template <int prefix_size, int element_size> | 6471 template <int prefix_size, int element_size> |
| 6329 int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) { | 6472 int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) { |
| 6330 uint32_t nof = NumberOfElements(); | 6473 uint32_t nof = NumberOfElements(); |
| 6331 if (nof == 0) return -1; // Bail out if empty. | 6474 if (nof == 0) return kNotFound; // Bail out if empty. |
| 6332 | 6475 |
| 6333 uint32_t capacity = Capacity(); | 6476 uint32_t capacity = Capacity(); |
| 6334 uint32_t hash = key->Hash(); | 6477 uint32_t hash = key->Hash(); |
| 6335 uint32_t entry = GetProbe(hash, 0, capacity); | 6478 uint32_t entry = GetProbe(hash, 0, capacity); |
| 6336 | 6479 |
| 6337 Object* element = KeyAt(entry); | 6480 Object* element = KeyAt(entry); |
| 6338 uint32_t passed_elements = 0; | 6481 uint32_t passed_elements = 0; |
| 6339 if (!element->IsNull()) { | 6482 if (!element->IsNull()) { |
| 6340 if (!element->IsUndefined() && key->IsMatch(element)) return entry; | 6483 if (!element->IsUndefined() && key->IsMatch(element)) return entry; |
| 6341 if (++passed_elements == nof) return -1; | 6484 if (++passed_elements == nof) return kNotFound; |
| 6342 } | 6485 } |
| 6343 for (uint32_t i = 1; !element->IsUndefined(); i++) { | 6486 for (uint32_t i = 1; !element->IsUndefined(); i++) { |
| 6344 entry = GetProbe(hash, i, capacity); | 6487 entry = GetProbe(hash, i, capacity); |
| 6345 element = KeyAt(entry); | 6488 element = KeyAt(entry); |
| 6346 if (!element->IsNull()) { | 6489 if (!element->IsNull()) { |
| 6347 if (!element->IsUndefined() && key->IsMatch(element)) return entry; | 6490 if (!element->IsUndefined() && key->IsMatch(element)) return entry; |
| 6348 if (++passed_elements == nof) return -1; | 6491 if (++passed_elements == nof) return kNotFound; |
| 6349 } | 6492 } |
| 6350 } | 6493 } |
| 6351 return -1; | 6494 return kNotFound; |
| 6352 } | 6495 } |
| 6353 | 6496 |
| 6354 | 6497 |
| 6355 template<int prefix_size, int element_size> | 6498 template<int prefix_size, int element_size> |
| 6356 Object* HashTable<prefix_size, element_size>::EnsureCapacity( | 6499 Object* HashTable<prefix_size, element_size>::EnsureCapacity( |
| 6357 int n, HashTableKey* key) { | 6500 int n, HashTableKey* key) { |
| 6358 int capacity = Capacity(); | 6501 int capacity = Capacity(); |
| 6359 int nof = NumberOfElements() + n; | 6502 int nof = NumberOfElements() + n; |
| 6360 // Make sure 25% is free | 6503 // Make sure 25% is free |
| 6361 if (nof + (nof >> 2) <= capacity) return this; | 6504 if (nof + (nof >> 2) <= capacity) return this; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6581 | 6724 |
| 6582 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 6725 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 6583 return Smi::FromInt(static_cast<int>(result)); | 6726 return Smi::FromInt(static_cast<int>(result)); |
| 6584 } | 6727 } |
| 6585 ASSERT_NE(NULL, result_double); | 6728 ASSERT_NE(NULL, result_double); |
| 6586 result_double->set_value(static_cast<double>(result)); | 6729 result_double->set_value(static_cast<double>(result)); |
| 6587 return result_double; | 6730 return result_double; |
| 6588 } | 6731 } |
| 6589 | 6732 |
| 6590 | 6733 |
| 6734 Object* JSGlobalObject::GetPropertyCell(LookupResult* result) { |
| 6735 ASSERT(!HasFastProperties()); |
| 6736 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 6737 ASSERT(value->IsJSGlobalPropertyCell()); |
| 6738 return value; |
| 6739 } |
| 6740 |
| 6741 |
| 6591 Object* SymbolTable::LookupString(String* string, Object** s) { | 6742 Object* SymbolTable::LookupString(String* string, Object** s) { |
| 6592 SymbolKey key(string); | 6743 SymbolKey key(string); |
| 6593 return LookupKey(&key, s); | 6744 return LookupKey(&key, s); |
| 6594 } | 6745 } |
| 6595 | 6746 |
| 6596 | 6747 |
| 6597 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { | 6748 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { |
| 6598 SymbolKey key(string); | 6749 SymbolKey key(string); |
| 6599 int entry = FindEntry(&key); | 6750 int entry = FindEntry(&key); |
| 6600 if (entry == -1) { | 6751 if (entry == kNotFound) { |
| 6601 return false; | 6752 return false; |
| 6602 } else { | 6753 } else { |
| 6603 String* result = String::cast(KeyAt(entry)); | 6754 String* result = String::cast(KeyAt(entry)); |
| 6604 ASSERT(StringShape(result).IsSymbol()); | 6755 ASSERT(StringShape(result).IsSymbol()); |
| 6605 *symbol = result; | 6756 *symbol = result; |
| 6606 return true; | 6757 return true; |
| 6607 } | 6758 } |
| 6608 } | 6759 } |
| 6609 | 6760 |
| 6610 | 6761 |
| 6611 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 6762 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { |
| 6612 Utf8SymbolKey key(str); | 6763 Utf8SymbolKey key(str); |
| 6613 return LookupKey(&key, s); | 6764 return LookupKey(&key, s); |
| 6614 } | 6765 } |
| 6615 | 6766 |
| 6616 | 6767 |
| 6617 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 6768 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
| 6618 int entry = FindEntry(key); | 6769 int entry = FindEntry(key); |
| 6619 | 6770 |
| 6620 // Symbol already in table. | 6771 // Symbol already in table. |
| 6621 if (entry != -1) { | 6772 if (entry != kNotFound) { |
| 6622 *s = KeyAt(entry); | 6773 *s = KeyAt(entry); |
| 6623 return this; | 6774 return this; |
| 6624 } | 6775 } |
| 6625 | 6776 |
| 6626 // Adding new symbol. Grow table if needed. | 6777 // Adding new symbol. Grow table if needed. |
| 6627 Object* obj = EnsureCapacity(1, key); | 6778 Object* obj = EnsureCapacity(1, key); |
| 6628 if (obj->IsFailure()) return obj; | 6779 if (obj->IsFailure()) return obj; |
| 6629 | 6780 |
| 6630 // Create symbol object. | 6781 // Create symbol object. |
| 6631 Object* symbol = key->GetObject(); | 6782 Object* symbol = key->GetObject(); |
| 6632 if (symbol->IsFailure()) return symbol; | 6783 if (symbol->IsFailure()) return symbol; |
| 6633 | 6784 |
| 6634 // If the symbol table grew as part of EnsureCapacity, obj is not | 6785 // If the symbol table grew as part of EnsureCapacity, obj is not |
| 6635 // the current symbol table and therefore we cannot use | 6786 // the current symbol table and therefore we cannot use |
| 6636 // SymbolTable::cast here. | 6787 // SymbolTable::cast here. |
| 6637 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); | 6788 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); |
| 6638 | 6789 |
| 6639 // Add the new symbol and return it along with the symbol table. | 6790 // Add the new symbol and return it along with the symbol table. |
| 6640 entry = table->FindInsertionEntry(symbol, key->Hash()); | 6791 entry = table->FindInsertionEntry(symbol, key->Hash()); |
| 6641 table->set(EntryToIndex(entry), symbol); | 6792 table->set(EntryToIndex(entry), symbol); |
| 6642 table->ElementAdded(); | 6793 table->ElementAdded(); |
| 6643 *s = symbol; | 6794 *s = symbol; |
| 6644 return table; | 6795 return table; |
| 6645 } | 6796 } |
| 6646 | 6797 |
| 6647 | 6798 |
| 6648 Object* CompilationCacheTable::Lookup(String* src) { | 6799 Object* CompilationCacheTable::Lookup(String* src) { |
| 6649 StringKey key(src); | 6800 StringKey key(src); |
| 6650 int entry = FindEntry(&key); | 6801 int entry = FindEntry(&key); |
| 6651 if (entry == -1) return Heap::undefined_value(); | 6802 if (entry == kNotFound) return Heap::undefined_value(); |
| 6652 return get(EntryToIndex(entry) + 1); | 6803 return get(EntryToIndex(entry) + 1); |
| 6653 } | 6804 } |
| 6654 | 6805 |
| 6655 | 6806 |
| 6656 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { | 6807 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { |
| 6657 StringSharedKey key(src, context->closure()->shared()); | 6808 StringSharedKey key(src, context->closure()->shared()); |
| 6658 int entry = FindEntry(&key); | 6809 int entry = FindEntry(&key); |
| 6659 if (entry == -1) return Heap::undefined_value(); | 6810 if (entry == kNotFound) return Heap::undefined_value(); |
| 6660 return get(EntryToIndex(entry) + 1); | 6811 return get(EntryToIndex(entry) + 1); |
| 6661 } | 6812 } |
| 6662 | 6813 |
| 6663 | 6814 |
| 6664 Object* CompilationCacheTable::LookupRegExp(String* src, | 6815 Object* CompilationCacheTable::LookupRegExp(String* src, |
| 6665 JSRegExp::Flags flags) { | 6816 JSRegExp::Flags flags) { |
| 6666 RegExpKey key(src, flags); | 6817 RegExpKey key(src, flags); |
| 6667 int entry = FindEntry(&key); | 6818 int entry = FindEntry(&key); |
| 6668 if (entry == -1) return Heap::undefined_value(); | 6819 if (entry == kNotFound) return Heap::undefined_value(); |
| 6669 return get(EntryToIndex(entry) + 1); | 6820 return get(EntryToIndex(entry) + 1); |
| 6670 } | 6821 } |
| 6671 | 6822 |
| 6672 | 6823 |
| 6673 Object* CompilationCacheTable::Put(String* src, Object* value) { | 6824 Object* CompilationCacheTable::Put(String* src, Object* value) { |
| 6674 StringKey key(src); | 6825 StringKey key(src); |
| 6675 Object* obj = EnsureCapacity(1, &key); | 6826 Object* obj = EnsureCapacity(1, &key); |
| 6676 if (obj->IsFailure()) return obj; | 6827 if (obj->IsFailure()) return obj; |
| 6677 | 6828 |
| 6678 CompilationCacheTable* cache = | 6829 CompilationCacheTable* cache = |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6757 bool IsStringKey() { return false; } | 6908 bool IsStringKey() { return false; } |
| 6758 | 6909 |
| 6759 private: | 6910 private: |
| 6760 FixedArray* symbols_; | 6911 FixedArray* symbols_; |
| 6761 }; | 6912 }; |
| 6762 | 6913 |
| 6763 | 6914 |
| 6764 Object* MapCache::Lookup(FixedArray* array) { | 6915 Object* MapCache::Lookup(FixedArray* array) { |
| 6765 SymbolsKey key(array); | 6916 SymbolsKey key(array); |
| 6766 int entry = FindEntry(&key); | 6917 int entry = FindEntry(&key); |
| 6767 if (entry == -1) return Heap::undefined_value(); | 6918 if (entry == kNotFound) return Heap::undefined_value(); |
| 6768 return get(EntryToIndex(entry) + 1); | 6919 return get(EntryToIndex(entry) + 1); |
| 6769 } | 6920 } |
| 6770 | 6921 |
| 6771 | 6922 |
| 6772 Object* MapCache::Put(FixedArray* array, Map* value) { | 6923 Object* MapCache::Put(FixedArray* array, Map* value) { |
| 6773 SymbolsKey key(array); | 6924 SymbolsKey key(array); |
| 6774 Object* obj = EnsureCapacity(1, &key); | 6925 Object* obj = EnsureCapacity(1, &key); |
| 6775 if (obj->IsFailure()) return obj; | 6926 if (obj->IsFailure()) return obj; |
| 6776 | 6927 |
| 6777 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 6928 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6908 int Dictionary::FindNumberEntry(uint32_t index) { | 7059 int Dictionary::FindNumberEntry(uint32_t index) { |
| 6909 NumberKey k(index); | 7060 NumberKey k(index); |
| 6910 return FindEntry(&k); | 7061 return FindEntry(&k); |
| 6911 } | 7062 } |
| 6912 | 7063 |
| 6913 | 7064 |
| 6914 Object* Dictionary::AtPut(HashTableKey* key, Object* value) { | 7065 Object* Dictionary::AtPut(HashTableKey* key, Object* value) { |
| 6915 int entry = FindEntry(key); | 7066 int entry = FindEntry(key); |
| 6916 | 7067 |
| 6917 // If the entry is present set the value; | 7068 // If the entry is present set the value; |
| 6918 if (entry != -1) { | 7069 if (entry != kNotFound) { |
| 6919 ValueAtPut(entry, value); | 7070 ValueAtPut(entry, value); |
| 6920 return this; | 7071 return this; |
| 6921 } | 7072 } |
| 6922 | 7073 |
| 6923 // Check whether the dictionary should be extended. | 7074 // Check whether the dictionary should be extended. |
| 6924 Object* obj = EnsureCapacity(1, key); | 7075 Object* obj = EnsureCapacity(1, key); |
| 6925 if (obj->IsFailure()) return obj; | 7076 if (obj->IsFailure()) return obj; |
| 6926 Object* k = key->GetObject(); | 7077 Object* k = key->GetObject(); |
| 6927 if (k->IsFailure()) return k; | 7078 if (k->IsFailure()) return k; |
| 6928 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 7079 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6981 Smi::FromInt(key << kRequiresSlowElementsTagSize), | 7132 Smi::FromInt(key << kRequiresSlowElementsTagSize), |
| 6982 SKIP_WRITE_BARRIER); | 7133 SKIP_WRITE_BARRIER); |
| 6983 } | 7134 } |
| 6984 } | 7135 } |
| 6985 | 7136 |
| 6986 | 7137 |
| 6987 Object* Dictionary::AddStringEntry(String* key, | 7138 Object* Dictionary::AddStringEntry(String* key, |
| 6988 Object* value, | 7139 Object* value, |
| 6989 PropertyDetails details) { | 7140 PropertyDetails details) { |
| 6990 StringKey k(key); | 7141 StringKey k(key); |
| 6991 SLOW_ASSERT(FindEntry(&k) == -1); | 7142 SLOW_ASSERT(FindEntry(&k) == kNotFound); |
| 6992 return Add(&k, value, details); | 7143 return Add(&k, value, details); |
| 6993 } | 7144 } |
| 6994 | 7145 |
| 6995 | 7146 |
| 6996 Object* Dictionary::AddNumberEntry(uint32_t key, | 7147 Object* Dictionary::AddNumberEntry(uint32_t key, |
| 6997 Object* value, | 7148 Object* value, |
| 6998 PropertyDetails details) { | 7149 PropertyDetails details) { |
| 6999 NumberKey k(key); | 7150 NumberKey k(key); |
| 7000 UpdateMaxNumberKey(key); | 7151 UpdateMaxNumberKey(key); |
| 7001 SLOW_ASSERT(FindEntry(&k) == -1); | 7152 SLOW_ASSERT(FindEntry(&k) == kNotFound); |
| 7002 return Add(&k, value, details); | 7153 return Add(&k, value, details); |
| 7003 } | 7154 } |
| 7004 | 7155 |
| 7005 | 7156 |
| 7006 Object* Dictionary::AtStringPut(String* key, Object* value) { | |
| 7007 StringKey k(key); | |
| 7008 return AtPut(&k, value); | |
| 7009 } | |
| 7010 | |
| 7011 | |
| 7012 Object* Dictionary::AtNumberPut(uint32_t key, Object* value) { | 7157 Object* Dictionary::AtNumberPut(uint32_t key, Object* value) { |
| 7013 NumberKey k(key); | 7158 NumberKey k(key); |
| 7014 UpdateMaxNumberKey(key); | 7159 UpdateMaxNumberKey(key); |
| 7015 return AtPut(&k, value); | 7160 return AtPut(&k, value); |
| 7016 } | 7161 } |
| 7017 | 7162 |
| 7018 | 7163 |
| 7019 Object* Dictionary::SetOrAddStringEntry(String* key, | 7164 Object* Dictionary::SetStringEntry(int entry, |
| 7020 Object* value, | 7165 String* key, |
| 7021 PropertyDetails details) { | 7166 Object* value, |
| 7022 StringKey k(key); | 7167 PropertyDetails details) { |
| 7023 int entry = FindEntry(&k); | |
| 7024 if (entry == -1) return AddStringEntry(key, value, details); | |
| 7025 // Preserve enumeration index. | 7168 // Preserve enumeration index. |
| 7026 details = PropertyDetails(details.attributes(), | 7169 details = PropertyDetails(details.attributes(), |
| 7027 details.type(), | 7170 details.type(), |
| 7028 DetailsAt(entry).index()); | 7171 DetailsAt(entry).index()); |
| 7029 SetEntry(entry, key, value, details); | 7172 SetEntry(entry, key, value, details); |
| 7030 return this; | 7173 return this; |
| 7031 } | 7174 } |
| 7032 | 7175 |
| 7033 | 7176 |
| 7034 Object* Dictionary::SetOrAddNumberEntry(uint32_t key, | 7177 Object* Dictionary::SetOrAddNumberEntry(uint32_t key, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7117 } | 7260 } |
| 7118 ASSERT(storage->length() >= index); | 7261 ASSERT(storage->length() >= index); |
| 7119 } | 7262 } |
| 7120 | 7263 |
| 7121 | 7264 |
| 7122 // Backwards lookup (slow). | 7265 // Backwards lookup (slow). |
| 7123 Object* Dictionary::SlowReverseLookup(Object* value) { | 7266 Object* Dictionary::SlowReverseLookup(Object* value) { |
| 7124 int capacity = Capacity(); | 7267 int capacity = Capacity(); |
| 7125 for (int i = 0; i < capacity; i++) { | 7268 for (int i = 0; i < capacity; i++) { |
| 7126 Object* k = KeyAt(i); | 7269 Object* k = KeyAt(i); |
| 7127 if (IsKey(k) && ValueAt(i) == value) { | 7270 if (IsKey(k)) { |
| 7128 return k; | 7271 Object* e = ValueAt(i); |
| 7272 if (e->IsJSGlobalPropertyCell()) { |
| 7273 e = JSGlobalPropertyCell::cast(e)->value(); |
| 7274 } |
| 7275 if (e == value) return k; |
| 7129 } | 7276 } |
| 7130 } | 7277 } |
| 7131 return Heap::undefined_value(); | 7278 return Heap::undefined_value(); |
| 7132 } | 7279 } |
| 7133 | 7280 |
| 7134 | 7281 |
| 7135 Object* Dictionary::TransformPropertiesToFastFor(JSObject* obj, | 7282 Object* Dictionary::TransformPropertiesToFastFor(JSObject* obj, |
| 7136 int unused_property_fields) { | 7283 int unused_property_fields) { |
| 7137 // Make sure we preserve dictionary representation if there are too many | 7284 // Make sure we preserve dictionary representation if there are too many |
| 7138 // descriptors. | 7285 // descriptors. |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7484 // No break point. | 7631 // No break point. |
| 7485 if (break_point_objects()->IsUndefined()) return 0; | 7632 if (break_point_objects()->IsUndefined()) return 0; |
| 7486 // Single beak point. | 7633 // Single beak point. |
| 7487 if (!break_point_objects()->IsFixedArray()) return 1; | 7634 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7488 // Multiple break points. | 7635 // Multiple break points. |
| 7489 return FixedArray::cast(break_point_objects())->length(); | 7636 return FixedArray::cast(break_point_objects())->length(); |
| 7490 } | 7637 } |
| 7491 #endif | 7638 #endif |
| 7492 | 7639 |
| 7493 } } // namespace v8::internal | 7640 } } // namespace v8::internal |
| OLD | NEW |