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 409007: Some optimizations for packer.js. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month 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
OLDNEW
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 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); 409 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
410 } 410 }
411 return value; 411 return value;
412 } 412 }
413 413
414 414
415 Object* JSObject::SetNormalizedProperty(String* name, 415 Object* JSObject::SetNormalizedProperty(String* name,
416 Object* value, 416 Object* value,
417 PropertyDetails details) { 417 PropertyDetails details) {
418 ASSERT(!HasFastProperties()); 418 ASSERT(!HasFastProperties());
419 // Optimization for packer.js. We make short keys into symbols to avoid
420 // constantly reallocating them.
Søren Thygesen Gjesse 2009/11/19 21:42:57 This code is duplicated below, please refactor.
Erik Corry 2009/11/20 10:12:46 Instead I removed this occurrence since it is very
421 if (!name->IsSymbol() && name->length() <= 2) {
422 Object* symbol_version = Heap::LookupSymbol(name);
423 if (!symbol_version->IsFailure()) name = String::cast(symbol_version);
424 }
419 int entry = property_dictionary()->FindEntry(name); 425 int entry = property_dictionary()->FindEntry(name);
420 if (entry == StringDictionary::kNotFound) { 426 if (entry == StringDictionary::kNotFound) {
421 Object* store_value = value; 427 Object* store_value = value;
422 if (IsGlobalObject()) { 428 if (IsGlobalObject()) {
423 store_value = Heap::AllocateJSGlobalPropertyCell(value); 429 store_value = Heap::AllocateJSGlobalPropertyCell(value);
424 if (store_value->IsFailure()) return store_value; 430 if (store_value->IsFailure()) return store_value;
425 } 431 }
426 Object* dict = property_dictionary()->Add(name, store_value, details); 432 Object* dict = property_dictionary()->Add(name, store_value, details);
427 if (dict->IsFailure()) return dict; 433 if (dict->IsFailure()) return dict;
428 set_properties(StringDictionary::cast(dict)); 434 set_properties(StringDictionary::cast(dict));
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 // Check local property, ignore interceptor. 1462 // Check local property, ignore interceptor.
1457 LookupResult result; 1463 LookupResult result;
1458 LocalLookupRealNamedProperty(name, &result); 1464 LocalLookupRealNamedProperty(name, &result);
1459 if (result.IsValid()) return SetProperty(&result, name, value, attributes); 1465 if (result.IsValid()) return SetProperty(&result, name, value, attributes);
1460 // Add real property. 1466 // Add real property.
1461 return AddProperty(name, value, attributes); 1467 return AddProperty(name, value, attributes);
1462 } 1468 }
1463 1469
1464 1470
1465 Object* JSObject::ReplaceSlowProperty(String* name, 1471 Object* JSObject::ReplaceSlowProperty(String* name,
1466 Object* value, 1472 Object* value,
1467 PropertyAttributes attributes) { 1473 PropertyAttributes attributes) {
1468 StringDictionary* dictionary = property_dictionary(); 1474 StringDictionary* dictionary = property_dictionary();
1469 int old_index = dictionary->FindEntry(name); 1475 int old_index = dictionary->FindEntry(name);
1470 int new_enumeration_index = 0; // 0 means "Use the next available index." 1476 int new_enumeration_index = 0; // 0 means "Use the next available index."
1471 if (old_index != -1) { 1477 if (old_index != -1) {
1472 // All calls to ReplaceSlowProperty have had all transitions removed. 1478 // All calls to ReplaceSlowProperty have had all transitions removed.
1473 ASSERT(!dictionary->DetailsAt(old_index).IsTransition()); 1479 ASSERT(!dictionary->DetailsAt(old_index).IsTransition());
1474 new_enumeration_index = dictionary->DetailsAt(old_index).index(); 1480 new_enumeration_index = dictionary->DetailsAt(old_index).index();
1475 } 1481 }
1476 1482
1477 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 1483 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
1478 return SetNormalizedProperty(name, value, new_details); 1484 return SetNormalizedProperty(name, value, new_details);
1479 } 1485 }
1480 1486
1487
1481 Object* JSObject::ConvertDescriptorToFieldAndMapTransition( 1488 Object* JSObject::ConvertDescriptorToFieldAndMapTransition(
1482 String* name, 1489 String* name,
1483 Object* new_value, 1490 Object* new_value,
1484 PropertyAttributes attributes) { 1491 PropertyAttributes attributes) {
1485 Map* old_map = map(); 1492 Map* old_map = map();
1486 Object* result = ConvertDescriptorToField(name, new_value, attributes); 1493 Object* result = ConvertDescriptorToField(name, new_value, attributes);
1487 if (result->IsFailure()) return result; 1494 if (result->IsFailure()) return result;
1488 // If we get to this point we have succeeded - do not return failure 1495 // If we get to this point we have succeeded - do not return failure
1489 // after this point. Later stuff is optional. 1496 // after this point. Later stuff is optional.
1490 if (!HasFastProperties()) { 1497 if (!HasFastProperties()) {
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 1869
1863 1870
1864 Object* JSObject::SetProperty(LookupResult* result, 1871 Object* JSObject::SetProperty(LookupResult* result,
1865 String* name, 1872 String* name,
1866 Object* value, 1873 Object* value,
1867 PropertyAttributes attributes) { 1874 PropertyAttributes attributes) {
1868 // Make sure that the top context does not change when doing callbacks or 1875 // Make sure that the top context does not change when doing callbacks or
1869 // interceptor calls. 1876 // interceptor calls.
1870 AssertNoContextChange ncc; 1877 AssertNoContextChange ncc;
1871 1878
1879 // Optimization for packer.js. We make short keys into symbols to avoid
1880 // constantly reallocating them.
1881 if (!name->IsSymbol() && name->length() <= 2) {
1882 Object* symbol_version = Heap::LookupSymbol(name);
1883 if (!symbol_version->IsFailure()) name = String::cast(symbol_version);
1884 }
1885
1872 // Check access rights if needed. 1886 // Check access rights if needed.
1873 if (IsAccessCheckNeeded() 1887 if (IsAccessCheckNeeded()
1874 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 1888 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
1875 return SetPropertyWithFailedAccessCheck(result, name, value); 1889 return SetPropertyWithFailedAccessCheck(result, name, value);
1876 } 1890 }
1877 1891
1878 if (IsJSGlobalProxy()) { 1892 if (IsJSGlobalProxy()) {
1879 Object* proto = GetPrototype(); 1893 Object* proto = GetPrototype();
1880 if (proto->IsNull()) return value; 1894 if (proto->IsNull()) return value;
1881 ASSERT(proto->IsJSGlobalObject()); 1895 ASSERT(proto->IsJSGlobalObject());
(...skipping 3351 matching lines...) Expand 10 before | Expand all | Expand 10 after
5233 } 5247 }
5234 set_elements(new_elements); 5248 set_elements(new_elements);
5235 return this; 5249 return this;
5236 } 5250 }
5237 5251
5238 5252
5239 void JSArray::Expand(int required_size) { 5253 void JSArray::Expand(int required_size) {
5240 Handle<JSArray> self(this); 5254 Handle<JSArray> self(this);
5241 Handle<FixedArray> old_backing(FixedArray::cast(elements())); 5255 Handle<FixedArray> old_backing(FixedArray::cast(elements()));
5242 int old_size = old_backing->length(); 5256 int old_size = old_backing->length();
5243 // Doubling in size would be overkill, but leave some slack to avoid 5257 int new_size = required_size > old_size ? required_size : old_size;
5244 // constantly growing.
5245 int new_size = required_size + (required_size >> 3);
5246 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); 5258 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size);
5247 // Can't use this any more now because we may have had a GC! 5259 // Can't use this any more now because we may have had a GC!
5248 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); 5260 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
5249 self->SetContent(*new_backing); 5261 self->SetContent(*new_backing);
5250 } 5262 }
5251 5263
5252 5264
5253 // Computes the new capacity when expanding the elements of a JSObject. 5265 // Computes the new capacity when expanding the elements of a JSObject.
5254 static int NewElementsCapacity(int old_capacity) { 5266 static int NewElementsCapacity(int old_capacity) {
5255 // (old_capacity + 50%) + 16 5267 // (old_capacity + 50%) + 16
(...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after
7320 } 7332 }
7321 } 7333 }
7322 7334
7323 7335
7324 Object* SymbolTable::LookupString(String* string, Object** s) { 7336 Object* SymbolTable::LookupString(String* string, Object** s) {
7325 SymbolKey key(string); 7337 SymbolKey key(string);
7326 return LookupKey(&key, s); 7338 return LookupKey(&key, s);
7327 } 7339 }
7328 7340
7329 7341
7342 // This class is used for looking up two character strings in the symbol table.
7343 // If we don't have a hit we don't want to waste much time so we unroll the
7344 // string hash calculation loop here for speed. Doesn't work if the two
7345 // characters form a decimal integer, since such strings have a different hash
7346 // algorithm.
7347 class TwoCharHashTableKey : public HashTableKey {
7348 public:
7349 TwoCharHashTableKey(uint32_t c1, uint32_t c2)
7350 : c1_(c1), c2_(c2) {
Søren Thygesen Gjesse 2009/11/19 21:42:57 How about ASSERT(c1 > '9' || c2 > '9') here? I see
Erik Corry 2009/11/20 10:12:46 Added a comment to the ASSERT_EQ below instead.
7351 // Char 1.
7352 uint32_t hash = c1 + (c1 << 10);
7353 hash ^= hash >> 6;
7354 // Char 2.
7355 hash += c2;
7356 hash += hash << 10;
7357 hash ^= hash >> 6;
7358 // GetHash.
7359 hash += hash << 3;
7360 hash ^= hash >> 11;
7361 hash += hash << 15;
7362 if (hash == 0) hash = 27;
7363 #ifdef DEBUG
7364 StringHasher hasher(2);
7365 hasher.AddCharacter(c1);
7366 hasher.AddCharacter(c2);
7367 ASSERT_EQ((int)hasher.GetHash(), (int)hash);
7368 #endif
7369 hash_ = hash;
7370 }
7371
7372 bool IsMatch(Object* o) {
7373 if (!o->IsString()) return false;
7374 String* other = String::cast(o);
7375 if (other->length() != 2) return false;
7376 if (other->Get(0) != c1_) return false;
7377 return other->Get(1) == c2_;
7378 }
7379
7380 uint32_t Hash() { return hash_; }
7381 uint32_t HashForObject(Object* key) {
7382 if (!key->IsString()) return 0;
7383 return String::cast(key)->Hash();
7384 }
7385
7386 Object* AsObject() {
7387 // The TwoCharHashTableKey is only used for looking in the symbol
7388 // table, not for adding to it.
7389 UNREACHABLE();
7390 return NULL;
7391 }
7392 private:
7393 uint32_t c1_;
7394 uint32_t c2_;
7395 uint32_t hash_;
7396 };
7397
7398
7330 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) { 7399 bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) {
7331 SymbolKey key(string); 7400 SymbolKey key(string);
7332 int entry = FindEntry(&key); 7401 int entry = FindEntry(&key);
7333 if (entry == kNotFound) { 7402 if (entry == kNotFound) {
7334 return false; 7403 return false;
7335 } else { 7404 } else {
7336 String* result = String::cast(KeyAt(entry)); 7405 String* result = String::cast(KeyAt(entry));
7337 ASSERT(StringShape(result).IsSymbol()); 7406 ASSERT(StringShape(result).IsSymbol());
7338 *symbol = result; 7407 *symbol = result;
7339 return true; 7408 return true;
7340 } 7409 }
7341 } 7410 }
7342 7411
7343 7412
7413 bool SymbolTable::LookupTwoCharsIfExists(uint32_t c1,
7414 uint32_t c2,
7415 String** symbol) {
7416 TwoCharHashTableKey key(c1, c2);
7417 int entry = FindEntry(&key);
7418 if (entry == kNotFound) {
7419 return false;
7420 } else {
7421 String* result = String::cast(KeyAt(entry));
7422 ASSERT(StringShape(result).IsSymbol());
7423 *symbol = result;
7424 return true;
7425 }
7426 }
7427
7428
7344 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { 7429 Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
7345 Utf8SymbolKey key(str); 7430 Utf8SymbolKey key(str);
7346 return LookupKey(&key, s); 7431 return LookupKey(&key, s);
7347 } 7432 }
7348 7433
7349 7434
7350 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { 7435 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
7351 int entry = FindEntry(key); 7436 int entry = FindEntry(key);
7352 7437
7353 // Symbol already in table. 7438 // Symbol already in table.
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
8204 if (break_point_objects()->IsUndefined()) return 0; 8289 if (break_point_objects()->IsUndefined()) return 0;
8205 // Single beak point. 8290 // Single beak point.
8206 if (!break_point_objects()->IsFixedArray()) return 1; 8291 if (!break_point_objects()->IsFixedArray()) return 1;
8207 // Multiple break points. 8292 // Multiple break points.
8208 return FixedArray::cast(break_point_objects())->length(); 8293 return FixedArray::cast(break_point_objects())->length();
8209 } 8294 }
8210 #endif 8295 #endif
8211 8296
8212 8297
8213 } } // namespace v8::internal 8298 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698