| 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 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { | 402 Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
| 403 ASSERT(!HasFastProperties()); | 403 ASSERT(!HasFastProperties()); |
| 404 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 404 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 405 if (IsJSGlobalObject()) { | 405 if (IsGlobalObject()) { |
| 406 value = JSGlobalPropertyCell::cast(value)->value(); | 406 value = JSGlobalPropertyCell::cast(value)->value(); |
| 407 } | 407 } |
| 408 ASSERT(!value->IsJSGlobalPropertyCell()); | 408 ASSERT(!value->IsJSGlobalPropertyCell()); |
| 409 return value; | 409 return value; |
| 410 } | 410 } |
| 411 | 411 |
| 412 | 412 |
| 413 Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) { | 413 Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) { |
| 414 ASSERT(!HasFastProperties()); | 414 ASSERT(!HasFastProperties()); |
| 415 if (IsJSGlobalObject()) { | 415 if (IsGlobalObject()) { |
| 416 JSGlobalPropertyCell* cell = | 416 JSGlobalPropertyCell* cell = |
| 417 JSGlobalPropertyCell::cast( | 417 JSGlobalPropertyCell::cast( |
| 418 property_dictionary()->ValueAt(result->GetDictionaryEntry())); | 418 property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
| 419 cell->set_value(value); | 419 cell->set_value(value); |
| 420 } else { | 420 } else { |
| 421 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 421 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 422 } | 422 } |
| 423 return value; | 423 return value; |
| 424 } | 424 } |
| 425 | 425 |
| 426 | 426 |
| 427 Object* JSObject::SetNormalizedProperty(String* name, | 427 Object* JSObject::SetNormalizedProperty(String* name, |
| 428 Object* value, | 428 Object* value, |
| 429 PropertyDetails details) { | 429 PropertyDetails details) { |
| 430 ASSERT(!HasFastProperties()); | 430 ASSERT(!HasFastProperties()); |
| 431 int entry = property_dictionary()->FindStringEntry(name); | 431 int entry = property_dictionary()->FindStringEntry(name); |
| 432 if (entry == Dictionary::kNotFound) { | 432 if (entry == Dictionary::kNotFound) { |
| 433 Object* store_value = value; | 433 Object* store_value = value; |
| 434 if (IsJSGlobalObject()) { | 434 if (IsGlobalObject()) { |
| 435 store_value = Heap::AllocateJSGlobalPropertyCell(value); | 435 store_value = Heap::AllocateJSGlobalPropertyCell(value); |
| 436 if (store_value->IsFailure()) return store_value; | 436 if (store_value->IsFailure()) return store_value; |
| 437 } | 437 } |
| 438 Object* dict = | 438 Object* dict = |
| 439 property_dictionary()->AddStringEntry(name, store_value, details); | 439 property_dictionary()->AddStringEntry(name, store_value, details); |
| 440 if (dict->IsFailure()) return dict; | 440 if (dict->IsFailure()) return dict; |
| 441 set_properties(Dictionary::cast(dict)); | 441 set_properties(Dictionary::cast(dict)); |
| 442 return value; | 442 return value; |
| 443 } | 443 } |
| 444 // Preserve enumeration index. | 444 // Preserve enumeration index. |
| 445 details = PropertyDetails(details.attributes(), | 445 details = PropertyDetails(details.attributes(), |
| 446 details.type(), | 446 details.type(), |
| 447 property_dictionary()->DetailsAt(entry).index()); | 447 property_dictionary()->DetailsAt(entry).index()); |
| 448 if (IsJSGlobalObject()) { | 448 if (IsGlobalObject()) { |
| 449 JSGlobalPropertyCell* cell = | 449 JSGlobalPropertyCell* cell = |
| 450 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); | 450 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); |
| 451 cell->set_value(value); | 451 cell->set_value(value); |
| 452 // Please note we have to update the property details. | 452 // Please note we have to update the property details. |
| 453 property_dictionary()->DetailsAtPut(entry, details); | 453 property_dictionary()->DetailsAtPut(entry, details); |
| 454 } else { | 454 } else { |
| 455 property_dictionary()->SetStringEntry(entry, name, value, details); | 455 property_dictionary()->SetStringEntry(entry, name, value, details); |
| 456 } | 456 } |
| 457 return value; | 457 return value; |
| 458 } | 458 } |
| 459 | 459 |
| 460 | 460 |
| 461 Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 461 Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
| 462 ASSERT(!HasFastProperties()); | 462 ASSERT(!HasFastProperties()); |
| 463 Dictionary* dictionary = property_dictionary(); | 463 Dictionary* dictionary = property_dictionary(); |
| 464 int entry = dictionary->FindStringEntry(name); | 464 int entry = dictionary->FindStringEntry(name); |
| 465 if (entry != Dictionary::kNotFound) { | 465 if (entry != Dictionary::kNotFound) { |
| 466 // If we have a global object set the cell to the hole. | 466 // If we have a global object set the cell to the hole. |
| 467 if (IsJSGlobalObject()) { | 467 if (IsGlobalObject()) { |
| 468 PropertyDetails details = dictionary->DetailsAt(entry); | 468 PropertyDetails details = dictionary->DetailsAt(entry); |
| 469 if (details.IsDontDelete() && mode != FORCE_DELETION) { | 469 if (details.IsDontDelete() && mode != FORCE_DELETION) { |
| 470 return Heap::false_value(); | 470 return Heap::false_value(); |
| 471 } | 471 } |
| 472 JSGlobalPropertyCell* cell = | 472 JSGlobalPropertyCell* cell = |
| 473 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 473 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
| 474 cell->set_value(Heap::the_hole_value()); | 474 cell->set_value(Heap::the_hole_value()); |
| 475 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 475 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 476 } else { | 476 } else { |
| 477 return dictionary->DeleteProperty(entry, mode); | 477 return dictionary->DeleteProperty(entry, mode); |
| (...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 | 1337 |
| 1338 // Add property in slow mode | 1338 // Add property in slow mode |
| 1339 Object* JSObject::AddSlowProperty(String* name, | 1339 Object* JSObject::AddSlowProperty(String* name, |
| 1340 Object* value, | 1340 Object* value, |
| 1341 PropertyAttributes attributes) { | 1341 PropertyAttributes attributes) { |
| 1342 ASSERT(!HasFastProperties()); | 1342 ASSERT(!HasFastProperties()); |
| 1343 Dictionary* dict = property_dictionary(); | 1343 Dictionary* dict = property_dictionary(); |
| 1344 Object* store_value = value; | 1344 Object* store_value = value; |
| 1345 if (IsJSGlobalObject()) { | 1345 if (IsGlobalObject()) { |
| 1346 // In case name is an orphaned property reuse the cell. | 1346 // In case name is an orphaned property reuse the cell. |
| 1347 int entry = dict->FindStringEntry(name); | 1347 int entry = dict->FindStringEntry(name); |
| 1348 if (entry != Dictionary::kNotFound) { | 1348 if (entry != Dictionary::kNotFound) { |
| 1349 store_value = dict->ValueAt(entry); | 1349 store_value = dict->ValueAt(entry); |
| 1350 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1350 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1351 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1351 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1352 dict->SetStringEntry(entry, name, store_value, details); | 1352 dict->SetStringEntry(entry, name, store_value, details); |
| 1353 return value; | 1353 return value; |
| 1354 } | 1354 } |
| 1355 store_value = Heap::AllocateJSGlobalPropertyCell(value); | 1355 store_value = Heap::AllocateJSGlobalPropertyCell(value); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 result->DisallowCaching(); | 1696 result->DisallowCaching(); |
| 1697 } | 1697 } |
| 1698 return; | 1698 return; |
| 1699 } | 1699 } |
| 1700 } else { | 1700 } else { |
| 1701 int entry = property_dictionary()->FindStringEntry(name); | 1701 int entry = property_dictionary()->FindStringEntry(name); |
| 1702 if (entry != Dictionary::kNotFound) { | 1702 if (entry != Dictionary::kNotFound) { |
| 1703 // Make sure to disallow caching for uninitialized constants | 1703 // Make sure to disallow caching for uninitialized constants |
| 1704 // found in the dictionary-mode objects. | 1704 // found in the dictionary-mode objects. |
| 1705 Object* value = property_dictionary()->ValueAt(entry); | 1705 Object* value = property_dictionary()->ValueAt(entry); |
| 1706 if (IsJSGlobalObject()) { | 1706 if (IsGlobalObject()) { |
| 1707 PropertyDetails d = property_dictionary()->DetailsAt(entry); | 1707 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
| 1708 if (d.IsDeleted()) { | 1708 if (d.IsDeleted()) { |
| 1709 result->NotFound(); | 1709 result->NotFound(); |
| 1710 return; | 1710 return; |
| 1711 } | 1711 } |
| 1712 value = JSGlobalPropertyCell::cast(value)->value(); | 1712 value = JSGlobalPropertyCell::cast(value)->value(); |
| 1713 ASSERT(result->IsLoaded()); | 1713 ASSERT(result->IsLoaded()); |
| 1714 } | 1714 } |
| 1715 if (value->IsTheHole()) { | 1715 if (value->IsTheHole()) { |
| 1716 result->DisallowCaching(); | 1716 result->DisallowCaching(); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 | 2107 |
| 2108 for (DescriptorReader r(map()->instance_descriptors()); | 2108 for (DescriptorReader r(map()->instance_descriptors()); |
| 2109 !r.eos(); | 2109 !r.eos(); |
| 2110 r.advance()) { | 2110 r.advance()) { |
| 2111 PropertyDetails details = r.GetDetails(); | 2111 PropertyDetails details = r.GetDetails(); |
| 2112 switch (details.type()) { | 2112 switch (details.type()) { |
| 2113 case CONSTANT_FUNCTION: { | 2113 case CONSTANT_FUNCTION: { |
| 2114 PropertyDetails d = | 2114 PropertyDetails d = |
| 2115 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2115 PropertyDetails(details.attributes(), NORMAL, details.index()); |
| 2116 Object* value = r.GetConstantFunction(); | 2116 Object* value = r.GetConstantFunction(); |
| 2117 if (IsJSGlobalObject()) { | 2117 if (IsGlobalObject()) { |
| 2118 value = Heap::AllocateJSGlobalPropertyCell(value); | 2118 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2119 if (value->IsFailure()) return value; | 2119 if (value->IsFailure()) return value; |
| 2120 } | 2120 } |
| 2121 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); | 2121 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
| 2122 if (result->IsFailure()) return result; | 2122 if (result->IsFailure()) return result; |
| 2123 dictionary = Dictionary::cast(result); | 2123 dictionary = Dictionary::cast(result); |
| 2124 break; | 2124 break; |
| 2125 } | 2125 } |
| 2126 case FIELD: { | 2126 case FIELD: { |
| 2127 PropertyDetails d = | 2127 PropertyDetails d = |
| 2128 PropertyDetails(details.attributes(), NORMAL, details.index()); | 2128 PropertyDetails(details.attributes(), NORMAL, details.index()); |
| 2129 Object* value = FastPropertyAt(r.GetFieldIndex()); | 2129 Object* value = FastPropertyAt(r.GetFieldIndex()); |
| 2130 if (IsJSGlobalObject()) { | 2130 if (IsGlobalObject()) { |
| 2131 value = Heap::AllocateJSGlobalPropertyCell(value); | 2131 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2132 if (value->IsFailure()) return value; | 2132 if (value->IsFailure()) return value; |
| 2133 } | 2133 } |
| 2134 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); | 2134 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
| 2135 if (result->IsFailure()) return result; | 2135 if (result->IsFailure()) return result; |
| 2136 dictionary = Dictionary::cast(result); | 2136 dictionary = Dictionary::cast(result); |
| 2137 break; | 2137 break; |
| 2138 } | 2138 } |
| 2139 case CALLBACKS: { | 2139 case CALLBACKS: { |
| 2140 PropertyDetails d = | 2140 PropertyDetails d = |
| 2141 PropertyDetails(details.attributes(), CALLBACKS, details.index()); | 2141 PropertyDetails(details.attributes(), CALLBACKS, details.index()); |
| 2142 Object* value = r.GetCallbacksObject(); | 2142 Object* value = r.GetCallbacksObject(); |
| 2143 if (IsJSGlobalObject()) { | 2143 if (IsGlobalObject()) { |
| 2144 value = Heap::AllocateJSGlobalPropertyCell(value); | 2144 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2145 if (value->IsFailure()) return value; | 2145 if (value->IsFailure()) return value; |
| 2146 } | 2146 } |
| 2147 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); | 2147 Object* result = dictionary->AddStringEntry(r.GetKey(), value, d); |
| 2148 if (result->IsFailure()) return result; | 2148 if (result->IsFailure()) return result; |
| 2149 dictionary = Dictionary::cast(result); | 2149 dictionary = Dictionary::cast(result); |
| 2150 break; | 2150 break; |
| 2151 } | 2151 } |
| 2152 case MAP_TRANSITION: | 2152 case MAP_TRANSITION: |
| 2153 case CONSTANT_TRANSITION: | 2153 case CONSTANT_TRANSITION: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 PrintF("Object properties have been normalized:\n"); | 2196 PrintF("Object properties have been normalized:\n"); |
| 2197 Print(); | 2197 Print(); |
| 2198 } | 2198 } |
| 2199 #endif | 2199 #endif |
| 2200 return this; | 2200 return this; |
| 2201 } | 2201 } |
| 2202 | 2202 |
| 2203 | 2203 |
| 2204 Object* JSObject::TransformToFastProperties(int unused_property_fields) { | 2204 Object* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 2205 if (HasFastProperties()) return this; | 2205 if (HasFastProperties()) return this; |
| 2206 ASSERT(!IsJSGlobalObject()); | 2206 ASSERT(!IsGlobalObject()); |
| 2207 return property_dictionary()-> | 2207 return property_dictionary()-> |
| 2208 TransformPropertiesToFastFor(this, unused_property_fields); | 2208 TransformPropertiesToFastFor(this, unused_property_fields); |
| 2209 } | 2209 } |
| 2210 | 2210 |
| 2211 | 2211 |
| 2212 Object* JSObject::NormalizeElements() { | 2212 Object* JSObject::NormalizeElements() { |
| 2213 if (!HasFastElements()) return this; | 2213 if (!HasFastElements()) return this; |
| 2214 | 2214 |
| 2215 // Get number of entries. | 2215 // Get number of entries. |
| 2216 FixedArray* array = FixedArray::cast(elements()); | 2216 FixedArray* array = FixedArray::cast(elements()); |
| 2217 | 2217 |
| 2218 // Compute the effective length. | 2218 // Compute the effective length. |
| (...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2733 elements->set_requires_slow_elements(); | 2733 elements->set_requires_slow_elements(); |
| 2734 // Set the potential new dictionary on the object. | 2734 // Set the potential new dictionary on the object. |
| 2735 set_elements(Dictionary::cast(dict)); | 2735 set_elements(Dictionary::cast(dict)); |
| 2736 } else { | 2736 } else { |
| 2737 // Normalize object to make this operation simple. | 2737 // Normalize object to make this operation simple. |
| 2738 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); | 2738 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2739 if (ok->IsFailure()) return ok; | 2739 if (ok->IsFailure()) return ok; |
| 2740 | 2740 |
| 2741 // For the global object allocate a new map to invalidate the global inline | 2741 // For the global object allocate a new map to invalidate the global inline |
| 2742 // caches which have a global property cell reference directly in the code. | 2742 // caches which have a global property cell reference directly in the code. |
| 2743 if (IsJSGlobalObject()) { | 2743 if (IsGlobalObject()) { |
| 2744 Object* new_map = map()->CopyDropDescriptors(); | 2744 Object* new_map = map()->CopyDropDescriptors(); |
| 2745 if (new_map->IsFailure()) return new_map; | 2745 if (new_map->IsFailure()) return new_map; |
| 2746 set_map(Map::cast(new_map)); | 2746 set_map(Map::cast(new_map)); |
| 2747 } | 2747 } |
| 2748 | 2748 |
| 2749 // Update the dictionary with the new CALLBACKS property. | 2749 // Update the dictionary with the new CALLBACKS property. |
| 2750 return SetNormalizedProperty(name, structure, details); | 2750 return SetNormalizedProperty(name, structure, details); |
| 2751 } | 2751 } |
| 2752 | 2752 |
| 2753 return structure; | 2753 return structure; |
| (...skipping 3978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6732 | 6732 |
| 6733 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 6733 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 6734 return Smi::FromInt(static_cast<int>(result)); | 6734 return Smi::FromInt(static_cast<int>(result)); |
| 6735 } | 6735 } |
| 6736 ASSERT_NE(NULL, result_double); | 6736 ASSERT_NE(NULL, result_double); |
| 6737 result_double->set_value(static_cast<double>(result)); | 6737 result_double->set_value(static_cast<double>(result)); |
| 6738 return result_double; | 6738 return result_double; |
| 6739 } | 6739 } |
| 6740 | 6740 |
| 6741 | 6741 |
| 6742 Object* JSGlobalObject::GetPropertyCell(LookupResult* result) { | 6742 Object* GlobalObject::GetPropertyCell(LookupResult* result) { |
| 6743 ASSERT(!HasFastProperties()); | 6743 ASSERT(!HasFastProperties()); |
| 6744 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 6744 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 6745 ASSERT(value->IsJSGlobalPropertyCell()); | 6745 ASSERT(value->IsJSGlobalPropertyCell()); |
| 6746 return value; | 6746 return value; |
| 6747 } | 6747 } |
| 6748 | 6748 |
| 6749 | 6749 |
| 6750 Object* SymbolTable::LookupString(String* string, Object** s) { | 6750 Object* SymbolTable::LookupString(String* string, Object** s) { |
| 6751 SymbolKey key(string); | 6751 SymbolKey key(string); |
| 6752 return LookupKey(&key, s); | 6752 return LookupKey(&key, s); |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7639 // No break point. | 7639 // No break point. |
| 7640 if (break_point_objects()->IsUndefined()) return 0; | 7640 if (break_point_objects()->IsUndefined()) return 0; |
| 7641 // Single beak point. | 7641 // Single beak point. |
| 7642 if (!break_point_objects()->IsFixedArray()) return 1; | 7642 if (!break_point_objects()->IsFixedArray()) return 1; |
| 7643 // Multiple break points. | 7643 // Multiple break points. |
| 7644 return FixedArray::cast(break_point_objects())->length(); | 7644 return FixedArray::cast(break_point_objects())->length(); |
| 7645 } | 7645 } |
| 7646 #endif | 7646 #endif |
| 7647 | 7647 |
| 7648 } } // namespace v8::internal | 7648 } } // namespace v8::internal |
| OLD | NEW |