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

Unified Diff: src/objects.cc

Issue 14425011: api: Object::CachedProperty Base URL: gh:v8/v8.git@master
Patch Set: globalize reference Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 68b913b3707f846877039686a8a8b3a9635de8d2..b98b3049b0d48d3398b6d9a1d33fab1478d536ce 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -15066,4 +15066,135 @@ void JSDate::SetLocalFields(int64_t local_time_ms, DateCache* date_cache) {
set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
}
+
+class LookupCacheEntry {
+ public:
+ LookupCacheEntry(Isolate* isolate, Map* map, LookupResult* result, int depth)
+ : map_(Handle<Map>::cast(isolate->global_handles()->Create(map))),
+ result_(*result),
+ depth_(depth) {
+ }
+
+ Handle<Map> map_;
+ LookupResult result_;
+ int depth_;
+};
+
+
+LookupCache::LookupCache(Isolate* isolate) : isolate_(isolate),
+ count_(0),
+ hidden_count_(0) {
+#ifdef DEBUG
+ for (int i = 0; i < kCacheEntryCount; i++) {
+ entries_[i] = NULL;
+ hidden_entries_[i] = NULL;
+ }
+#endif
+}
+
+
+LookupCache::~LookupCache() {
+ for (int i = 0; i < count_; i++) {
+ delete entries_[i];
+ entries_[i] = NULL;
+ }
+ count_ = 0;
+ for (int i = 0; i < hidden_count_; i++) {
+ delete hidden_entries_[i];
+ hidden_entries_[i] = NULL;
+ }
+ hidden_count_ = 0;
+}
+
+
+void LookupCache::Lookup(Handle<Object> obj,
+ Handle<Name> name,
+ LookupResult* result,
+ bool set_property) {
+ if (!obj->IsJSReceiver()) return obj->Lookup(*name, result);
+
+ JSReceiver* receiver = JSReceiver::cast(*obj);
+ Heap* heap = receiver->GetHeap();
+ Map* map = receiver->map();
+
+ int count = set_property ? hidden_count_ : count_;
+ LookupCacheEntry** entries = set_property ? hidden_entries_ : entries_;
+ for (int i = 0; i < count; i++) {
+ LookupCacheEntry* entry = entries[i];
+ if (*entry->map_ != map) continue;
+
+ // Hit! Dive into prototype chain if needed
+ Object* current = *obj;
+ int depth = entry->depth_;
+ for (int j = 0; j < depth; j++) {
+ // XXX: Probably this is a fatal condition
+ if (current == heap->null_value()) break;
+
+ current = JSObject::cast(current)->GetPrototype();
+ }
+ result->CopyFrom(&entry->result_, JSObject::cast(receiver));
+
+ return;
+ }
+
+ // Miss
+ // Ecma-262 3rd 8.6.2.4
+ int depth = 0;
+ if (set_property) {
+ receiver->LocalLookup(*name, result, true);
+ if (!result->IsFound()) {
+ map->LookupTransition(JSObject::cast(*obj),
+ *name,
+ result);
+ }
+ } else {
+ Object* current;
+ for (current = *obj;
+ current != heap->null_value();
+ current = JSObject::cast(current)->GetPrototype(), depth++) {
+ JSReceiver::cast(current)->LocalLookup(*name, result, false);
+ if (result->IsFound()) break;
+ }
+ if (current == heap->null_value()) result->NotFound();
+ }
+
+ // If property wasn't found, or is not cacheable
+ if (!result->IsFound() && result->IsCacheable()) return;
+
+ // Cache is full, just return result
+ if (count == kCacheEntryCount) return;
+
+ // Insert new cache entry
+ entries[count++] = new LookupCacheEntry(isolate_, map, result, depth);
+
+ // Update count
+ if (set_property) {
+ hidden_count_ = count;
+ } else {
+ count_ = count;
+ }
+}
+
+
+MUST_USE_RESULT MaybeObject* LookupCache::GetProperty(Handle<Object> obj,
+ Handle<Name> name) {
+ PropertyAttributes attributes;
+ LookupResult result(isolate_);
+ Lookup(obj, name, &result);
+ MaybeObject* value = obj->GetProperty(*obj, &result, *name, &attributes);
+ ASSERT(attributes <= ABSENT);
+ return value;
+}
+
+
+MUST_USE_RESULT MaybeObject* LookupCache::SetProperty(Handle<Object> obj,
+ Handle<Name> name,
+ Handle<Object> value) {
+ ASSERT(obj->IsJSReceiver());
+ LookupResult result(isolate_);
+ Lookup(obj, name, &result, true);
+ JSReceiver* receiver = JSReceiver::cast(*obj);
+ return receiver->SetProperty(&result, *name, *value, NONE, kNonStrictMode);
+}
+
} } // namespace v8::internal
« no previous file with comments | « src/objects.h ('k') | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698