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 |