Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/objects.cc

Issue 42066: Changed runtime system to preserve the global property cells for deleted prop... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/global/
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 } 428 }
429 return value; 429 return value;
430 } 430 }
431 431
432 432
433 Object* JSObject::SetNormalizedProperty(String* name, 433 Object* JSObject::SetNormalizedProperty(String* name,
434 Object* value, 434 Object* value,
435 PropertyDetails details) { 435 PropertyDetails details) {
436 ASSERT(!HasFastProperties()); 436 ASSERT(!HasFastProperties());
437 int entry = property_dictionary()->FindStringEntry(name); 437 int entry = property_dictionary()->FindStringEntry(name);
438 if (entry == -1) { 438 if (entry == Dictionary::kNotFound) {
439 Object* store_value = value; 439 Object* store_value = value;
440 if (IsJSGlobalObject()) { 440 if (IsJSGlobalObject()) {
441 store_value = Heap::AllocateJSGlobalPropertyCell(value); 441 store_value = Heap::AllocateJSGlobalPropertyCell(value);
442 if (store_value->IsFailure()) return store_value; 442 if (store_value->IsFailure()) return store_value;
443 } 443 }
444 Object* dict = 444 Object* dict =
445 property_dictionary()->AddStringEntry(name, store_value, details); 445 property_dictionary()->AddStringEntry(name, store_value, details);
446 if (dict->IsFailure()) return dict; 446 if (dict->IsFailure()) return dict;
447 set_properties(Dictionary::cast(dict)); 447 set_properties(Dictionary::cast(dict));
448 return value; 448 return value;
449 } 449 }
450 // Preserve enumeration index. 450 // Preserve enumeration index.
451 details = PropertyDetails(details.attributes(), 451 details = PropertyDetails(details.attributes(),
452 details.type(), 452 details.type(),
453 property_dictionary()->DetailsAt(entry).index()); 453 property_dictionary()->DetailsAt(entry).index());
454 if (IsJSGlobalObject()) { 454 if (IsJSGlobalObject()) {
455 JSGlobalPropertyCell* cell = 455 JSGlobalPropertyCell* cell =
456 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); 456 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
457 cell->set_value(value); 457 cell->set_value(value);
458 // Please note we have to update the property details. 458 // Please note we have to update the property details.
459 property_dictionary()->SetStringEntry(entry, name, cell, details); 459 property_dictionary()->DetailsAtPut(entry, details);
460 } else { 460 } else {
461 property_dictionary()->SetStringEntry(entry, name, value, details); 461 property_dictionary()->SetStringEntry(entry, name, value, details);
462 } 462 }
463 return value; 463 return value;
464 } 464 }
465 465
466 466
467 Object* JSObject::DeleteNormalizedProperty(String* name) {
468 ASSERT(!HasFastProperties());
469 Dictionary* dictionary = property_dictionary();
470 int entry = dictionary->FindStringEntry(name);
471 if (entry != Dictionary::kNotFound) {
472 PropertyDetails details = dictionary->DetailsAt(entry);
473 if (details.IsDontDelete()) return Heap::false_value();
474 // If we have a global object set the cell to the hole.
475 if (IsJSGlobalObject()) {
476 JSGlobalPropertyCell* cell =
477 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry));
478 cell->set_value(Heap::the_hole_value());
479 dictionary->DetailsAtPut(entry, details.AsDeleted());
480 } else {
481 return dictionary->DeleteProperty(entry);
482 }
483 }
484 return Heap::true_value();
485 }
486
487
467 Object* Object::GetProperty(Object* receiver, 488 Object* Object::GetProperty(Object* receiver,
468 LookupResult* result, 489 LookupResult* result,
469 String* name, 490 String* name,
470 PropertyAttributes* attributes) { 491 PropertyAttributes* attributes) {
471 // Make sure that the top context does not change when doing 492 // Make sure that the top context does not change when doing
472 // callbacks or interceptor calls. 493 // callbacks or interceptor calls.
473 AssertNoContextChange ncc; 494 AssertNoContextChange ncc;
474 495
475 // Traverse the prototype chain from the current object (this) to 496 // Traverse the prototype chain from the current object (this) to
476 // the holder and check for access rights. This avoid traversing the 497 // the holder and check for access rights. This avoid traversing the
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 1337 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
1317 1338
1318 return function; 1339 return function;
1319 } 1340 }
1320 1341
1321 1342
1322 // Add property in slow mode 1343 // Add property in slow mode
1323 Object* JSObject::AddSlowProperty(String* name, 1344 Object* JSObject::AddSlowProperty(String* name,
1324 Object* value, 1345 Object* value,
1325 PropertyAttributes attributes) { 1346 PropertyAttributes attributes) {
1326 PropertyDetails details = PropertyDetails(attributes, NORMAL); 1347 ASSERT(!HasFastProperties());
1348 Dictionary* dict = property_dictionary();
1327 Object* store_value = value; 1349 Object* store_value = value;
1328 if (IsJSGlobalObject()) { 1350 if (IsJSGlobalObject()) {
1351 // In case name is an orphaned property reuse the cell.
1352 int entry = dict->FindStringEntry(name);
1353 if (entry != Dictionary::kNotFound) {
1354 store_value = dict->ValueAt(entry);
1355 JSGlobalPropertyCell::cast(store_value)->set_value(value);
1356 PropertyDetails details = PropertyDetails(attributes, NORMAL);
1357 dict->SetStringEntry(entry, name, store_value, details);
1358 return value;
1359 }
1329 store_value = Heap::AllocateJSGlobalPropertyCell(value); 1360 store_value = Heap::AllocateJSGlobalPropertyCell(value);
1330 if (store_value->IsFailure()) return store_value; 1361 if (store_value->IsFailure()) return store_value;
1362 JSGlobalPropertyCell::cast(store_value)->set_value(value);
1331 } 1363 }
1332 Object* result = property_dictionary()->AddStringEntry(name, 1364 PropertyDetails details = PropertyDetails(attributes, NORMAL);
1333 store_value, 1365 Object* result = dict->AddStringEntry(name, store_value, details);
1334 details);
1335 if (result->IsFailure()) return result; 1366 if (result->IsFailure()) return result;
1336 if (property_dictionary() != result) { 1367 if (dict != result) set_properties(Dictionary::cast(result));
1337 set_properties(Dictionary::cast(result));
1338 }
1339 return value; 1368 return value;
1340 } 1369 }
1341 1370
1342 1371
1343 Object* JSObject::AddProperty(String* name, 1372 Object* JSObject::AddProperty(String* name,
1344 Object* value, 1373 Object* value,
1345 PropertyAttributes attributes) { 1374 PropertyAttributes attributes) {
1346 ASSERT(!IsJSGlobalProxy()); 1375 ASSERT(!IsJSGlobalProxy());
1347 if (HasFastProperties()) { 1376 if (HasFastProperties()) {
1348 // Ensure the descriptor array does not get too big. 1377 // Ensure the descriptor array does not get too big.
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 // Disallow caching for uninitialized constants. These can only 1665 // Disallow caching for uninitialized constants. These can only
1637 // occur as fields. 1666 // occur as fields.
1638 if (result->IsReadOnly() && result->type() == FIELD && 1667 if (result->IsReadOnly() && result->type() == FIELD &&
1639 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) { 1668 FastPropertyAt(result->GetFieldIndex())->IsTheHole()) {
1640 result->DisallowCaching(); 1669 result->DisallowCaching();
1641 } 1670 }
1642 return; 1671 return;
1643 } 1672 }
1644 } else { 1673 } else {
1645 int entry = property_dictionary()->FindStringEntry(name); 1674 int entry = property_dictionary()->FindStringEntry(name);
1646 if (entry != DescriptorArray::kNotFound) { 1675 if (entry != Dictionary::kNotFound) {
1647 // Make sure to disallow caching for uninitialized constants 1676 // Make sure to disallow caching for uninitialized constants
1648 // found in the dictionary-mode objects. 1677 // found in the dictionary-mode objects.
1649 Object* value = property_dictionary()->ValueAt(entry); 1678 Object* value = property_dictionary()->ValueAt(entry);
1650 if (IsJSGlobalObject()) { 1679 if (IsJSGlobalObject()) {
1680 PropertyDetails d = property_dictionary()->DetailsAt(entry);
1681 if (d.IsDeleted()) {
1682 result->NotFound();
1683 return;
1684 }
1651 value = JSGlobalPropertyCell::cast(value)->value(); 1685 value = JSGlobalPropertyCell::cast(value)->value();
1652 } 1686 }
1653 if (value->IsTheHole()) { 1687 if (value->IsTheHole()) {
1654 result->DisallowCaching(); 1688 result->DisallowCaching();
1655 } 1689 }
1656 result->DictionaryResult(this, entry); 1690 result->DictionaryResult(this, entry);
1657 return; 1691 return;
1658 } 1692 }
1659 // Slow case object skipped during lookup. Do not use inline caching. 1693 // Slow case object skipped during lookup. Do not use inline caching.
1660 result->DisallowCaching(); 1694 result->DisallowCaching();
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 Object* JSObject::DeletePropertyPostInterceptor(String* name) { 2212 Object* JSObject::DeletePropertyPostInterceptor(String* name) {
2179 // Check local property, ignore interceptor. 2213 // Check local property, ignore interceptor.
2180 LookupResult result; 2214 LookupResult result;
2181 LocalLookupRealNamedProperty(name, &result); 2215 LocalLookupRealNamedProperty(name, &result);
2182 if (!result.IsValid()) return Heap::true_value(); 2216 if (!result.IsValid()) return Heap::true_value();
2183 2217
2184 // Normalize object if needed. 2218 // Normalize object if needed.
2185 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2219 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
2186 if (obj->IsFailure()) return obj; 2220 if (obj->IsFailure()) return obj;
2187 2221
2188 ASSERT(!HasFastProperties()); 2222 return DeleteNormalizedProperty(name);
2189 // Attempt to remove the property from the property dictionary.
2190 Dictionary* dictionary = property_dictionary();
2191 int entry = dictionary->FindStringEntry(name);
2192 if (entry != -1) return dictionary->DeleteProperty(entry);
2193 return Heap::true_value();
2194 } 2223 }
2195 2224
2196 2225
2197 Object* JSObject::DeletePropertyWithInterceptor(String* name) { 2226 Object* JSObject::DeletePropertyWithInterceptor(String* name) {
2198 HandleScope scope; 2227 HandleScope scope;
2199 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2228 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2200 Handle<String> name_handle(name); 2229 Handle<String> name_handle(name);
2201 Handle<JSObject> this_handle(this); 2230 Handle<JSObject> this_handle(this);
2202 if (!interceptor->deleter()->IsUndefined()) { 2231 if (!interceptor->deleter()->IsUndefined()) {
2203 v8::NamedPropertyDeleter deleter = 2232 v8::NamedPropertyDeleter deleter =
(...skipping 27 matching lines...) Expand all
2231 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2260 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2232 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2261 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2233 if (index < length) { 2262 if (index < length) {
2234 FixedArray::cast(elements())->set_the_hole(index); 2263 FixedArray::cast(elements())->set_the_hole(index);
2235 } 2264 }
2236 return Heap::true_value(); 2265 return Heap::true_value();
2237 } 2266 }
2238 ASSERT(!HasFastElements()); 2267 ASSERT(!HasFastElements());
2239 Dictionary* dictionary = element_dictionary(); 2268 Dictionary* dictionary = element_dictionary();
2240 int entry = dictionary->FindNumberEntry(index); 2269 int entry = dictionary->FindNumberEntry(index);
2241 if (entry != -1) return dictionary->DeleteProperty(entry); 2270 if (entry != Dictionary::kNotFound) return dictionary->DeleteProperty(entry);
2242 return Heap::true_value(); 2271 return Heap::true_value();
2243 } 2272 }
2244 2273
2245 2274
2246 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { 2275 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) {
2247 // Make sure that the top context does not change when doing 2276 // Make sure that the top context does not change when doing
2248 // callbacks or interceptor calls. 2277 // callbacks or interceptor calls.
2249 AssertNoContextChange ncc; 2278 AssertNoContextChange ncc;
2250 HandleScope scope; 2279 HandleScope scope;
2251 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 2280 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 uint32_t length = IsJSArray() ? 2327 uint32_t length = IsJSArray() ?
2299 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2328 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2300 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2329 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2301 if (index < length) { 2330 if (index < length) {
2302 FixedArray::cast(elements())->set_the_hole(index); 2331 FixedArray::cast(elements())->set_the_hole(index);
2303 } 2332 }
2304 return Heap::true_value(); 2333 return Heap::true_value();
2305 } else { 2334 } else {
2306 Dictionary* dictionary = element_dictionary(); 2335 Dictionary* dictionary = element_dictionary();
2307 int entry = dictionary->FindNumberEntry(index); 2336 int entry = dictionary->FindNumberEntry(index);
2308 if (entry != -1) return dictionary->DeleteProperty(entry); 2337 if (entry != Dictionary::kNotFound) {
2338 return dictionary->DeleteProperty(entry);
2339 }
2309 } 2340 }
2310 return Heap::true_value(); 2341 return Heap::true_value();
2311 } 2342 }
2312 2343
2313 2344
2314 Object* JSObject::DeleteProperty(String* name) { 2345 Object* JSObject::DeleteProperty(String* name) {
2315 // ECMA-262, 3rd, 8.6.2.5 2346 // ECMA-262, 3rd, 8.6.2.5
2316 ASSERT(name->IsString()); 2347 ASSERT(name->IsString());
2317 2348
2318 // Check access rights if needed. 2349 // Check access rights if needed.
(...skipping 22 matching lines...) Expand all
2341 if (result.type() == INTERCEPTOR) { 2372 if (result.type() == INTERCEPTOR) {
2342 return DeletePropertyWithInterceptor(name); 2373 return DeletePropertyWithInterceptor(name);
2343 } 2374 }
2344 if (!result.IsLoaded()) { 2375 if (!result.IsLoaded()) {
2345 return JSObject::cast(this)->DeleteLazyProperty(&result, name); 2376 return JSObject::cast(this)->DeleteLazyProperty(&result, name);
2346 } 2377 }
2347 // Normalize object if needed. 2378 // Normalize object if needed.
2348 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); 2379 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
2349 if (obj->IsFailure()) return obj; 2380 if (obj->IsFailure()) return obj;
2350 // Make sure the properties are normalized before removing the entry. 2381 // Make sure the properties are normalized before removing the entry.
2351 Dictionary* dictionary = property_dictionary(); 2382 return DeleteNormalizedProperty(name);
2352 int entry = dictionary->FindStringEntry(name);
2353 if (entry != -1) return dictionary->DeleteProperty(entry);
2354 return Heap::true_value();
2355 } 2383 }
2356 } 2384 }
2357 2385
2358 2386
2359 // Check whether this object references another object. 2387 // Check whether this object references another object.
2360 bool JSObject::ReferencesObject(Object* obj) { 2388 bool JSObject::ReferencesObject(Object* obj) {
2361 AssertNoAllocation no_alloc; 2389 AssertNoAllocation no_alloc;
2362 2390
2363 // Is the object the constructor for this object? 2391 // Is the object the constructor for this object?
2364 if (map()->constructor() == obj) { 2392 if (map()->constructor() == obj) {
(...skipping 2689 matching lines...) Expand 10 before | Expand all | Expand 10 after
5054 if (HasFastElements()) { 5082 if (HasFastElements()) {
5055 uint32_t length = IsJSArray() ? 5083 uint32_t length = IsJSArray() ?
5056 static_cast<uint32_t>( 5084 static_cast<uint32_t>(
5057 Smi::cast(JSArray::cast(this)->length())->value()) : 5085 Smi::cast(JSArray::cast(this)->length())->value()) :
5058 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 5086 static_cast<uint32_t>(FixedArray::cast(elements())->length());
5059 if ((index < length) && 5087 if ((index < length) &&
5060 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 5088 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
5061 return true; 5089 return true;
5062 } 5090 }
5063 } else { 5091 } else {
5064 if (element_dictionary()->FindNumberEntry(index) != -1) return true; 5092 if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) {
5093 return true;
5094 }
5065 } 5095 }
5066 5096
5067 // Handle [] on String objects. 5097 // Handle [] on String objects.
5068 if (this->IsStringObjectWithCharacterAt(index)) return true; 5098 if (this->IsStringObjectWithCharacterAt(index)) return true;
5069 5099
5070 Object* pt = GetPrototype(); 5100 Object* pt = GetPrototype();
5071 if (pt == Heap::null_value()) return false; 5101 if (pt == Heap::null_value()) return false;
5072 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 5102 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
5073 } 5103 }
5074 5104
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5129 if (this->IsStringObjectWithCharacterAt(index)) return true; 5159 if (this->IsStringObjectWithCharacterAt(index)) return true;
5130 5160
5131 if (HasFastElements()) { 5161 if (HasFastElements()) {
5132 uint32_t length = IsJSArray() ? 5162 uint32_t length = IsJSArray() ?
5133 static_cast<uint32_t>( 5163 static_cast<uint32_t>(
5134 Smi::cast(JSArray::cast(this)->length())->value()) : 5164 Smi::cast(JSArray::cast(this)->length())->value()) :
5135 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 5165 static_cast<uint32_t>(FixedArray::cast(elements())->length());
5136 return (index < length) && 5166 return (index < length) &&
5137 !FixedArray::cast(elements())->get(index)->IsTheHole(); 5167 !FixedArray::cast(elements())->get(index)->IsTheHole();
5138 } else { 5168 } else {
5139 return element_dictionary()->FindNumberEntry(index) != -1; 5169 return element_dictionary()->FindNumberEntry(index)
5170 != Dictionary::kNotFound;
5140 } 5171 }
5141 } 5172 }
5142 5173
5143 5174
5144 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { 5175 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
5145 // Check access rights if needed. 5176 // Check access rights if needed.
5146 if (IsAccessCheckNeeded() && 5177 if (IsAccessCheckNeeded() &&
5147 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 5178 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
5148 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 5179 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
5149 return false; 5180 return false;
5150 } 5181 }
5151 5182
5152 // Check for lookup interceptor 5183 // Check for lookup interceptor
5153 if (HasIndexedInterceptor()) { 5184 if (HasIndexedInterceptor()) {
5154 return HasElementWithInterceptor(receiver, index); 5185 return HasElementWithInterceptor(receiver, index);
5155 } 5186 }
5156 5187
5157 if (HasFastElements()) { 5188 if (HasFastElements()) {
5158 uint32_t length = IsJSArray() ? 5189 uint32_t length = IsJSArray() ?
5159 static_cast<uint32_t>( 5190 static_cast<uint32_t>(
5160 Smi::cast(JSArray::cast(this)->length())->value()) : 5191 Smi::cast(JSArray::cast(this)->length())->value()) :
5161 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 5192 static_cast<uint32_t>(FixedArray::cast(elements())->length());
5162 if ((index < length) && 5193 if ((index < length) &&
5163 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; 5194 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
5164 } else { 5195 } else {
5165 if (element_dictionary()->FindNumberEntry(index) != -1) return true; 5196 if (element_dictionary()->FindNumberEntry(index) != Dictionary::kNotFound) {
5197 return true;
5198 }
5166 } 5199 }
5167 5200
5168 // Handle [] on String objects. 5201 // Handle [] on String objects.
5169 if (this->IsStringObjectWithCharacterAt(index)) return true; 5202 if (this->IsStringObjectWithCharacterAt(index)) return true;
5170 5203
5171 Object* pt = GetPrototype(); 5204 Object* pt = GetPrototype();
5172 if (pt == Heap::null_value()) return false; 5205 if (pt == Heap::null_value()) return false;
5173 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 5206 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
5174 } 5207 }
5175 5208
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
5363 // JSArray::length cannot change. 5396 // JSArray::length cannot change.
5364 if (HasFastElements()) { 5397 if (HasFastElements()) {
5365 FixedArray* elms = FixedArray::cast(elements()); 5398 FixedArray* elms = FixedArray::cast(elements());
5366 if (index < static_cast<uint32_t>(elms->length())) { 5399 if (index < static_cast<uint32_t>(elms->length())) {
5367 Object* value = elms->get(index); 5400 Object* value = elms->get(index);
5368 if (!value->IsTheHole()) return value; 5401 if (!value->IsTheHole()) return value;
5369 } 5402 }
5370 } else { 5403 } else {
5371 Dictionary* dictionary = element_dictionary(); 5404 Dictionary* dictionary = element_dictionary();
5372 int entry = dictionary->FindNumberEntry(index); 5405 int entry = dictionary->FindNumberEntry(index);
5373 if (entry != -1) { 5406 if (entry != Dictionary::kNotFound) {
5374 return dictionary->ValueAt(entry); 5407 return dictionary->ValueAt(entry);
5375 } 5408 }
5376 } 5409 }
5377 5410
5378 // Continue searching via the prototype chain. 5411 // Continue searching via the prototype chain.
5379 Object* pt = GetPrototype(); 5412 Object* pt = GetPrototype();
5380 if (pt == Heap::null_value()) return Heap::undefined_value(); 5413 if (pt == Heap::null_value()) return Heap::undefined_value();
5381 return pt->GetElementWithReceiver(receiver, index); 5414 return pt->GetElementWithReceiver(receiver, index);
5382 } 5415 }
5383 5416
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5433 // JSArray::length cannot change. 5466 // JSArray::length cannot change.
5434 if (HasFastElements()) { 5467 if (HasFastElements()) {
5435 FixedArray* elms = FixedArray::cast(elements()); 5468 FixedArray* elms = FixedArray::cast(elements());
5436 if (index < static_cast<uint32_t>(elms->length())) { 5469 if (index < static_cast<uint32_t>(elms->length())) {
5437 Object* value = elms->get(index); 5470 Object* value = elms->get(index);
5438 if (!value->IsTheHole()) return value; 5471 if (!value->IsTheHole()) return value;
5439 } 5472 }
5440 } else { 5473 } else {
5441 Dictionary* dictionary = element_dictionary(); 5474 Dictionary* dictionary = element_dictionary();
5442 int entry = dictionary->FindNumberEntry(index); 5475 int entry = dictionary->FindNumberEntry(index);
5443 if (entry != -1) { 5476 if (entry != Dictionary::kNotFound) {
5444 return dictionary->ValueAt(entry); 5477 return dictionary->ValueAt(entry);
5445 } 5478 }
5446 } 5479 }
5447 5480
5448 Object* pt = GetPrototype(); 5481 Object* pt = GetPrototype();
5449 if (pt == Heap::null_value()) return Heap::undefined_value(); 5482 if (pt == Heap::null_value()) return Heap::undefined_value();
5450 return pt->GetElementWithReceiver(receiver, index); 5483 return pt->GetElementWithReceiver(receiver, index);
5451 } 5484 }
5452 5485
5453 5486
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
5693 if (this->IsStringObjectWithCharacterAt(index)) return true; 5726 if (this->IsStringObjectWithCharacterAt(index)) return true;
5694 5727
5695 if (HasFastElements()) { 5728 if (HasFastElements()) {
5696 uint32_t length = IsJSArray() ? 5729 uint32_t length = IsJSArray() ?
5697 static_cast<uint32_t>( 5730 static_cast<uint32_t>(
5698 Smi::cast(JSArray::cast(this)->length())->value()) : 5731 Smi::cast(JSArray::cast(this)->length())->value()) :
5699 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 5732 static_cast<uint32_t>(FixedArray::cast(elements())->length());
5700 return (index < length) && 5733 return (index < length) &&
5701 !FixedArray::cast(elements())->get(index)->IsTheHole(); 5734 !FixedArray::cast(elements())->get(index)->IsTheHole();
5702 } 5735 }
5703 return element_dictionary()->FindNumberEntry(index) != -1; 5736 return element_dictionary()->FindNumberEntry(index)
5737 != Dictionary::kNotFound;
5704 } 5738 }
5705 5739
5706 5740
5707 bool JSObject::HasRealNamedCallbackProperty(String* key) { 5741 bool JSObject::HasRealNamedCallbackProperty(String* key) {
5708 // Check access rights if needed. 5742 // Check access rights if needed.
5709 if (IsAccessCheckNeeded() && 5743 if (IsAccessCheckNeeded() &&
5710 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { 5744 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) {
5711 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 5745 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
5712 return false; 5746 return false;
5713 } 5747 }
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
6224 HashTable::cast(obj)->SetCapacity(capacity); 6258 HashTable::cast(obj)->SetCapacity(capacity);
6225 } 6259 }
6226 return obj; 6260 return obj;
6227 } 6261 }
6228 6262
6229 6263
6230 // Find entry for key otherwise return -1. 6264 // Find entry for key otherwise return -1.
6231 template <int prefix_size, int element_size> 6265 template <int prefix_size, int element_size>
6232 int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) { 6266 int HashTable<prefix_size, element_size>::FindEntry(HashTableKey* key) {
6233 uint32_t nof = NumberOfElements(); 6267 uint32_t nof = NumberOfElements();
6234 if (nof == 0) return -1; // Bail out if empty. 6268 if (nof == 0) return kNotFound; // Bail out if empty.
6235 6269
6236 uint32_t capacity = Capacity(); 6270 uint32_t capacity = Capacity();
6237 uint32_t hash = key->Hash(); 6271 uint32_t hash = key->Hash();
6238 uint32_t entry = GetProbe(hash, 0, capacity); 6272 uint32_t entry = GetProbe(hash, 0, capacity);
6239 6273
6240 Object* element = KeyAt(entry); 6274 Object* element = KeyAt(entry);
6241 uint32_t passed_elements = 0; 6275 uint32_t passed_elements = 0;
6242 if (!element->IsNull()) { 6276 if (!element->IsNull()) {
6243 if (!element->IsUndefined() && key->IsMatch(element)) return entry; 6277 if (!element->IsUndefined() && key->IsMatch(element)) return entry;
6244 if (++passed_elements == nof) return -1; 6278 if (++passed_elements == nof) return kNotFound;
6245 } 6279 }
6246 for (uint32_t i = 1; !element->IsUndefined(); i++) { 6280 for (uint32_t i = 1; !element->IsUndefined(); i++) {
6247 entry = GetProbe(hash, i, capacity); 6281 entry = GetProbe(hash, i, capacity);
6248 element = KeyAt(entry); 6282 element = KeyAt(entry);
6249 if (!element->IsNull()) { 6283 if (!element->IsNull()) {
6250 if (!element->IsUndefined() && key->IsMatch(element)) return entry; 6284 if (!element->IsUndefined() && key->IsMatch(element)) return entry;
6251 if (++passed_elements == nof) return -1; 6285 if (++passed_elements == nof) return kNotFound;
6252 } 6286 }
6253 } 6287 }
6254 return -1; 6288 return kNotFound;
6255 } 6289 }
6256 6290
6257 6291
6258 template<int prefix_size, int element_size> 6292 template<int prefix_size, int element_size>
6259 Object* HashTable<prefix_size, element_size>::EnsureCapacity( 6293 Object* HashTable<prefix_size, element_size>::EnsureCapacity(
6260 int n, HashTableKey* key) { 6294 int n, HashTableKey* key) {
6261 int capacity = Capacity(); 6295 int capacity = Capacity();
6262 int nof = NumberOfElements() + n; 6296 int nof = NumberOfElements() + n;
6263 // Make sure 25% is free 6297 // Make sure 25% is free
6264 if (nof + (nof >> 2) <= capacity) return this; 6298 if (nof + (nof >> 2) <= capacity) return this;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
6321 6355
6322 Object* SymbolTable::LookupString(String* string, Object** s) { 6356 Object* SymbolTable::LookupString(String* string, Object** s) {
6323 SymbolKey key(string); 6357 SymbolKey key(string);
6324 return LookupKey(&key, s); 6358 return LookupKey(&key, s);
6325 } 6359 }
6326 6360
6327 6361
6328 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { 6362 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) {
6329 SymbolKey key(string); 6363 SymbolKey key(string);
6330 int entry = FindEntry(&key); 6364 int entry = FindEntry(&key);
6331 if (entry == -1) { 6365 if (entry == kNotFound) {
6332 return false; 6366 return false;
6333 } else { 6367 } else {
6334 String* result = String::cast(KeyAt(entry)); 6368 String* result = String::cast(KeyAt(entry));
6335 ASSERT(StringShape(result).IsSymbol()); 6369 ASSERT(StringShape(result).IsSymbol());
6336 *symbol = result; 6370 *symbol = result;
6337 return true; 6371 return true;
6338 } 6372 }
6339 } 6373 }
6340 6374
6341 6375
6342 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { 6376 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
6343 Utf8SymbolKey key(str); 6377 Utf8SymbolKey key(str);
6344 return LookupKey(&key, s); 6378 return LookupKey(&key, s);
6345 } 6379 }
6346 6380
6347 6381
6348 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { 6382 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
6349 int entry = FindEntry(key); 6383 int entry = FindEntry(key);
6350 6384
6351 // Symbol already in table. 6385 // Symbol already in table.
6352 if (entry != -1) { 6386 if (entry != kNotFound) {
6353 *s = KeyAt(entry); 6387 *s = KeyAt(entry);
6354 return this; 6388 return this;
6355 } 6389 }
6356 6390
6357 // Adding new symbol. Grow table if needed. 6391 // Adding new symbol. Grow table if needed.
6358 Object* obj = EnsureCapacity(1, key); 6392 Object* obj = EnsureCapacity(1, key);
6359 if (obj->IsFailure()) return obj; 6393 if (obj->IsFailure()) return obj;
6360 6394
6361 // Create symbol object. 6395 // Create symbol object.
6362 Object* symbol = key->GetObject(); 6396 Object* symbol = key->GetObject();
6363 if (symbol->IsFailure()) return symbol; 6397 if (symbol->IsFailure()) return symbol;
6364 6398
6365 // If the symbol table grew as part of EnsureCapacity, obj is not 6399 // If the symbol table grew as part of EnsureCapacity, obj is not
6366 // the current symbol table and therefore we cannot use 6400 // the current symbol table and therefore we cannot use
6367 // SymbolTable::cast here. 6401 // SymbolTable::cast here.
6368 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); 6402 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj);
6369 6403
6370 // Add the new symbol and return it along with the symbol table. 6404 // Add the new symbol and return it along with the symbol table.
6371 entry = table->FindInsertionEntry(symbol, key->Hash()); 6405 entry = table->FindInsertionEntry(symbol, key->Hash());
6372 table->set(EntryToIndex(entry), symbol); 6406 table->set(EntryToIndex(entry), symbol);
6373 table->ElementAdded(); 6407 table->ElementAdded();
6374 *s = symbol; 6408 *s = symbol;
6375 return table; 6409 return table;
6376 } 6410 }
6377 6411
6378 6412
6379 Object* CompilationCacheTable::Lookup(String* src) { 6413 Object* CompilationCacheTable::Lookup(String* src) {
6380 StringKey key(src); 6414 StringKey key(src);
6381 int entry = FindEntry(&key); 6415 int entry = FindEntry(&key);
6382 if (entry == -1) return Heap::undefined_value(); 6416 if (entry == kNotFound) return Heap::undefined_value();
6383 return get(EntryToIndex(entry) + 1); 6417 return get(EntryToIndex(entry) + 1);
6384 } 6418 }
6385 6419
6386 6420
6387 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { 6421 Object* CompilationCacheTable::LookupEval(String* src, Context* context) {
6388 StringSharedKey key(src, context->closure()->shared()); 6422 StringSharedKey key(src, context->closure()->shared());
6389 int entry = FindEntry(&key); 6423 int entry = FindEntry(&key);
6390 if (entry == -1) return Heap::undefined_value(); 6424 if (entry == kNotFound) return Heap::undefined_value();
6391 return get(EntryToIndex(entry) + 1); 6425 return get(EntryToIndex(entry) + 1);
6392 } 6426 }
6393 6427
6394 6428
6395 Object* CompilationCacheTable::LookupRegExp(String* src, 6429 Object* CompilationCacheTable::LookupRegExp(String* src,
6396 JSRegExp::Flags flags) { 6430 JSRegExp::Flags flags) {
6397 RegExpKey key(src, flags); 6431 RegExpKey key(src, flags);
6398 int entry = FindEntry(&key); 6432 int entry = FindEntry(&key);
6399 if (entry == -1) return Heap::undefined_value(); 6433 if (entry == kNotFound) return Heap::undefined_value();
6400 return get(EntryToIndex(entry) + 1); 6434 return get(EntryToIndex(entry) + 1);
6401 } 6435 }
6402 6436
6403 6437
6404 Object* CompilationCacheTable::Put(String* src, Object* value) { 6438 Object* CompilationCacheTable::Put(String* src, Object* value) {
6405 StringKey key(src); 6439 StringKey key(src);
6406 Object* obj = EnsureCapacity(1, &key); 6440 Object* obj = EnsureCapacity(1, &key);
6407 if (obj->IsFailure()) return obj; 6441 if (obj->IsFailure()) return obj;
6408 6442
6409 CompilationCacheTable* cache = 6443 CompilationCacheTable* cache =
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
6539 6573
6540 private: 6574 private:
6541 Map* map_; 6575 Map* map_;
6542 String* name_; 6576 String* name_;
6543 }; 6577 };
6544 6578
6545 6579
6546 Object* MapCache::Lookup(FixedArray* array) { 6580 Object* MapCache::Lookup(FixedArray* array) {
6547 SymbolsKey key(array); 6581 SymbolsKey key(array);
6548 int entry = FindEntry(&key); 6582 int entry = FindEntry(&key);
6549 if (entry == -1) return Heap::undefined_value(); 6583 if (entry == kNotFound) return Heap::undefined_value();
6550 return get(EntryToIndex(entry) + 1); 6584 return get(EntryToIndex(entry) + 1);
6551 } 6585 }
6552 6586
6553 6587
6554 Object* MapCache::Put(FixedArray* array, Map* value) { 6588 Object* MapCache::Put(FixedArray* array, Map* value) {
6555 SymbolsKey key(array); 6589 SymbolsKey key(array);
6556 Object* obj = EnsureCapacity(1, &key); 6590 Object* obj = EnsureCapacity(1, &key);
6557 if (obj->IsFailure()) return obj; 6591 if (obj->IsFailure()) return obj;
6558 6592
6559 MapCache* cache = reinterpret_cast<MapCache*>(obj); 6593 MapCache* cache = reinterpret_cast<MapCache*>(obj);
6560 int entry = cache->FindInsertionEntry(array, key.Hash()); 6594 int entry = cache->FindInsertionEntry(array, key.Hash());
6561 cache->set(EntryToIndex(entry), array); 6595 cache->set(EntryToIndex(entry), array);
6562 cache->set(EntryToIndex(entry) + 1, value); 6596 cache->set(EntryToIndex(entry) + 1, value);
6563 cache->ElementAdded(); 6597 cache->ElementAdded();
6564 return cache; 6598 return cache;
6565 } 6599 }
6566 6600
6567 6601
6568 int LookupCache::Lookup(Map* map, String* name) { 6602 int LookupCache::Lookup(Map* map, String* name) {
6569 MapNameKey key(map, name); 6603 MapNameKey key(map, name);
6570 int entry = FindEntry(&key); 6604 int entry = FindEntry(&key);
6571 if (entry == -1) return kNotFound; 6605 if (entry == kNotFound) return kNotFound;
6572 return Smi::cast(get(EntryToIndex(entry) + 1))->value(); 6606 return Smi::cast(get(EntryToIndex(entry) + 1))->value();
6573 } 6607 }
6574 6608
6575 6609
6576 Object* LookupCache::Put(Map* map, String* name, int value) { 6610 Object* LookupCache::Put(Map* map, String* name, int value) {
6577 MapNameKey key(map, name); 6611 MapNameKey key(map, name);
6578 Object* obj = EnsureCapacity(1, &key); 6612 Object* obj = EnsureCapacity(1, &key);
6579 if (obj->IsFailure()) return obj; 6613 if (obj->IsFailure()) return obj;
6580 Object* k = key.GetObject(); 6614 Object* k = key.GetObject();
6581 if (k->IsFailure()) return k; 6615 if (k->IsFailure()) return k;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
6712 int Dictionary::FindNumberEntry(uint32_t index) { 6746 int Dictionary::FindNumberEntry(uint32_t index) {
6713 NumberKey k(index); 6747 NumberKey k(index);
6714 return FindEntry(&k); 6748 return FindEntry(&k);
6715 } 6749 }
6716 6750
6717 6751
6718 Object* Dictionary::AtPut(HashTableKey* key, Object* value) { 6752 Object* Dictionary::AtPut(HashTableKey* key, Object* value) {
6719 int entry = FindEntry(key); 6753 int entry = FindEntry(key);
6720 6754
6721 // If the entry is present set the value; 6755 // If the entry is present set the value;
6722 if (entry != -1) { 6756 if (entry != kNotFound) {
6723 ValueAtPut(entry, value); 6757 ValueAtPut(entry, value);
6724 return this; 6758 return this;
6725 } 6759 }
6726 6760
6727 // Check whether the dictionary should be extended. 6761 // Check whether the dictionary should be extended.
6728 Object* obj = EnsureCapacity(1, key); 6762 Object* obj = EnsureCapacity(1, key);
6729 if (obj->IsFailure()) return obj; 6763 if (obj->IsFailure()) return obj;
6730 Object* k = key->GetObject(); 6764 Object* k = key->GetObject();
6731 if (k->IsFailure()) return k; 6765 if (k->IsFailure()) return k;
6732 PropertyDetails details = PropertyDetails(NONE, NORMAL); 6766 PropertyDetails details = PropertyDetails(NONE, NORMAL);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
6787 Smi::FromInt(key << kRequiresSlowElementsTagSize), 6821 Smi::FromInt(key << kRequiresSlowElementsTagSize),
6788 SKIP_WRITE_BARRIER); 6822 SKIP_WRITE_BARRIER);
6789 } 6823 }
6790 } 6824 }
6791 6825
6792 6826
6793 Object* Dictionary::AddStringEntry(String* key, 6827 Object* Dictionary::AddStringEntry(String* key,
6794 Object* value, 6828 Object* value,
6795 PropertyDetails details) { 6829 PropertyDetails details) {
6796 StringKey k(key); 6830 StringKey k(key);
6797 SLOW_ASSERT(FindEntry(&k) == -1); 6831 SLOW_ASSERT(FindEntry(&k) == kNotFound);
6798 return Add(&k, value, details); 6832 return Add(&k, value, details);
6799 } 6833 }
6800 6834
6801 6835
6802 Object* Dictionary::AddNumberEntry(uint32_t key, 6836 Object* Dictionary::AddNumberEntry(uint32_t key,
6803 Object* value, 6837 Object* value,
6804 PropertyDetails details) { 6838 PropertyDetails details) {
6805 NumberKey k(key); 6839 NumberKey k(key);
6806 UpdateMaxNumberKey(key); 6840 UpdateMaxNumberKey(key);
6807 SLOW_ASSERT(FindEntry(&k) == -1); 6841 SLOW_ASSERT(FindEntry(&k) == kNotFound);
6808 return Add(&k, value, details); 6842 return Add(&k, value, details);
6809 } 6843 }
6810 6844
6811 6845
6812 Object* Dictionary::AtNumberPut(uint32_t key, Object* value) { 6846 Object* Dictionary::AtNumberPut(uint32_t key, Object* value) {
6813 NumberKey k(key); 6847 NumberKey k(key);
6814 UpdateMaxNumberKey(key); 6848 UpdateMaxNumberKey(key);
6815 return AtPut(&k, value); 6849 return AtPut(&k, value);
6816 } 6850 }
6817 6851
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
7339 // No break point. 7373 // No break point.
7340 if (break_point_objects()->IsUndefined()) return 0; 7374 if (break_point_objects()->IsUndefined()) return 0;
7341 // Single beak point. 7375 // Single beak point.
7342 if (!break_point_objects()->IsFixedArray()) return 1; 7376 if (!break_point_objects()->IsFixedArray()) return 1;
7343 // Multiple break points. 7377 // Multiple break points.
7344 return FixedArray::cast(break_point_objects())->length(); 7378 return FixedArray::cast(break_point_objects())->length();
7345 } 7379 }
7346 7380
7347 7381
7348 } } // namespace v8::internal 7382 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698