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

Side by Side Diff: src/runtime.cc

Issue 7879: Introduce a lookup cache class in the runtime system and use it for... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 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
« src/objects.cc ('K') | « src/objects-inl.h ('k') | no next file » | 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // First find prefix of consecutive symbol keys. 106 // First find prefix of consecutive symbol keys.
107 int number_of_properties = constant_properties->length()/2; 107 int number_of_properties = constant_properties->length()/2;
108 int number_of_symbol_keys = 0; 108 int number_of_symbol_keys = 0;
109 while ((number_of_symbol_keys < number_of_properties) && 109 while ((number_of_symbol_keys < number_of_properties) &&
110 (constant_properties->get(number_of_symbol_keys*2)->IsSymbol())) { 110 (constant_properties->get(number_of_symbol_keys*2)->IsSymbol())) {
111 number_of_symbol_keys++; 111 number_of_symbol_keys++;
112 } 112 }
113 // Based on the number of prefix symbols key we decide whether 113 // Based on the number of prefix symbols key we decide whether
114 // to use the map cache in the global context. 114 // to use the map cache in the global context.
115 const int kMaxKeys = 10; 115 const int kMaxKeys = 10;
116 if ((number_of_symbol_keys == number_of_properties) 116 if ((number_of_symbol_keys == number_of_properties) &&
117 && (number_of_symbol_keys < kMaxKeys)) { 117 (number_of_symbol_keys < kMaxKeys)) {
118 // Create the fixed array with the key. 118 // Create the fixed array with the key.
119 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); 119 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys);
120 for (int i = 0; i < number_of_symbol_keys; i++) { 120 for (int i = 0; i < number_of_symbol_keys; i++) {
121 keys->set(i, constant_properties->get(i*2)); 121 keys->set(i, constant_properties->get(i*2));
122 } 122 }
123 is_result_from_cache = true; 123 is_result_from_cache = true;
124 return Factory::ObjectLiteralMapFromCache(context, keys); 124 return Factory::ObjectLiteralMapFromCache(context, keys);
125 } 125 }
126 } 126 }
127 is_result_from_cache = false; 127 is_result_from_cache = false;
(...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 ASSERT(args.length() == 2); 1662 ASSERT(args.length() == 2);
1663 1663
1664 Handle<Object> object = args.at<Object>(0); 1664 Handle<Object> object = args.at<Object>(0);
1665 Handle<Object> key = args.at<Object>(1); 1665 Handle<Object> key = args.at<Object>(1);
1666 1666
1667 return Runtime::GetObjectProperty(object, key); 1667 return Runtime::GetObjectProperty(object, key);
1668 } 1668 }
1669 1669
1670 1670
1671 1671
1672 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric 1672 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric.
1673 static Object* Runtime_KeyedGetProperty(Arguments args) { 1673 static Object* Runtime_KeyedGetProperty(Arguments args) {
1674 NoHandleAllocation ha; 1674 NoHandleAllocation ha;
1675 ASSERT(args.length() == 2); 1675 ASSERT(args.length() == 2);
1676 1676
1677 Object* receiver = args[0]; 1677 // Fast cases for getting named properties of the receiver JSObject
1678 Object* key = args[1]; 1678 // itself. The global proxy objects has to be excluded since
1679 if (receiver->IsJSObject() && 1679 // LocalLookup on the global proxy object can return a valid result
1680 key->IsString() && 1680 // eventhough the global proxy object never has properties. This is
1681 !JSObject::cast(receiver)->HasFastProperties()) { 1681 // the case because the global proxy object forwards everything to
1682 Dictionary* dictionary = JSObject::cast(receiver)->property_dictionary(); 1682 // its hidden prototype including local lookups.
1683 int entry = dictionary->FindStringEntry(String::cast(key)); 1683 if (args[0]->IsJSObject() &&
1684 if ((entry != DescriptorArray::kNotFound) 1684 !args[0]->IsJSGlobalProxy() &&
1685 && (dictionary->DetailsAt(entry).type() == NORMAL)) { 1685 args[1]->IsString()) {
1686 return dictionary->ValueAt(entry); 1686 JSObject* receiver = JSObject::cast(args[0]);
1687 String* key = String::cast(args[1]);
1688 if (receiver->HasFastProperties()) {
1689 // Attempt to use lookup cache.
1690 Object* obj = Heap::GetKeyedLookupCache();
1691 if (obj->IsFailure()) return obj;
1692 LookupCache* cache = LookupCache::cast(obj);
1693 Map* receiver_map = receiver->map();
1694 int offset = cache->Lookup(receiver_map, key);
bak 2008/10/23 06:08:11 It might be a good idea to use a kNotFound constan
1695 if (offset != -1) {
1696 Object* value = receiver->FastPropertyAt(offset);
1697 return value->IsTheHole() ? Heap::undefined_value() : value;
1698 }
1699 // Lookup cache miss. Perform lookup and update the cache if
1700 // appropriate.
1701 LookupResult result;
1702 receiver->LocalLookup(key, &result);
1703 if (result.IsProperty() && result.IsLoaded() && result.type() == FIELD) {
1704 int offset = result.GetFieldIndex();
1705 Object* obj = cache->Put(receiver_map, key, offset);
1706 if (obj->IsFailure()) return obj;
1707 Heap::SetKeyedLookupCache(LookupCache::cast(obj));
1708 Object* value = receiver->FastPropertyAt(offset);
1709 return value->IsTheHole() ? Heap::undefined_value() : value;
1710 }
1711 } else {
1712 // Attempt dictionary lookup.
1713 Dictionary* dictionary = receiver->property_dictionary();
1714 int entry = dictionary->FindStringEntry(key);
1715 if ((entry != DescriptorArray::kNotFound) &&
1716 (dictionary->DetailsAt(entry).type() == NORMAL)) {
1717 return dictionary->ValueAt(entry);
1718 }
1687 } 1719 }
1688 } 1720 }
1721
1722 // Fall back to GetObjectProperty.
1689 return Runtime::GetObjectProperty(args.at<Object>(0), 1723 return Runtime::GetObjectProperty(args.at<Object>(0),
1690 args.at<Object>(1)); 1724 args.at<Object>(1));
1691 } 1725 }
1692 1726
1693 1727
1694 Object* Runtime::SetObjectProperty(Handle<Object> object, 1728 Object* Runtime::SetObjectProperty(Handle<Object> object,
1695 Handle<Object> key, 1729 Handle<Object> key,
1696 Handle<Object> value, 1730 Handle<Object> value,
1697 PropertyAttributes attr) { 1731 PropertyAttributes attr) {
1698 HandleScope scope; 1732 HandleScope scope;
(...skipping 3751 matching lines...) Expand 10 before | Expand all | Expand 10 after
5450 5484
5451 void Runtime::PerformGC(Object* result) { 5485 void Runtime::PerformGC(Object* result) {
5452 Failure* failure = Failure::cast(result); 5486 Failure* failure = Failure::cast(result);
5453 // Try to do a garbage collection; ignore it if it fails. The C 5487 // Try to do a garbage collection; ignore it if it fails. The C
5454 // entry stub will throw an out-of-memory exception in that case. 5488 // entry stub will throw an out-of-memory exception in that case.
5455 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); 5489 Heap::CollectGarbage(failure->requested(), failure->allocation_space());
5456 } 5490 }
5457 5491
5458 5492
5459 } } // namespace v8::internal 5493 } } // namespace v8::internal
OLDNEW
« src/objects.cc ('K') | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698