OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 15048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15059 set_cache_stamp(date_cache->stamp()); | 15059 set_cache_stamp(date_cache->stamp()); |
15060 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 15060 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
15061 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 15061 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
15062 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 15062 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
15063 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 15063 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
15064 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 15064 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
15065 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 15065 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
15066 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 15066 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
15067 } | 15067 } |
15068 | 15068 |
15069 | |
15070 class LookupCacheEntry { | |
15071 public: | |
15072 LookupCacheEntry(Map* map, LookupResult* result, int depth) | |
15073 : map_(map), | |
15074 result_(*result), | |
15075 depth_(depth) { | |
15076 } | |
15077 | |
15078 Map* map_; | |
danno
2013/04/29 11:30:11
Oh no! These are naked heap pointers. This approac
| |
15079 LookupResult result_; | |
15080 int depth_; | |
15081 }; | |
15082 | |
15083 | |
15084 LookupCache::LookupCache(Isolate* isolate) : isolate_(isolate), | |
15085 count_(0), | |
15086 hidden_count_(0) { | |
15087 #ifdef DEBUG | |
15088 for (int i = 0; i < kCacheEntryCount; i++) { | |
15089 entries_[i] = NULL; | |
15090 hidden_entries_[i] = NULL; | |
15091 } | |
15092 #endif | |
15093 } | |
15094 | |
15095 | |
15096 LookupCache::~LookupCache() { | |
15097 for (int i = 0; i < count_; i++) { | |
15098 delete entries_[i]; | |
15099 entries_[i] = NULL; | |
15100 } | |
15101 count_ = 0; | |
15102 for (int i = 0; i < hidden_count_; i++) { | |
15103 delete hidden_entries_[i]; | |
15104 hidden_entries_[i] = NULL; | |
15105 } | |
15106 hidden_count_ = 0; | |
15107 } | |
15108 | |
15109 | |
15110 void LookupCache::Lookup(Handle<Object> obj, | |
15111 Handle<Name> name, | |
15112 LookupResult* result, | |
15113 bool set_property) { | |
15114 if (!obj->IsJSReceiver()) return obj->Lookup(*name, result); | |
15115 | |
15116 JSReceiver* receiver = JSReceiver::cast(*obj); | |
15117 Heap* heap = receiver->GetHeap(); | |
15118 Map* map = receiver->map(); | |
15119 | |
15120 int count = set_property ? hidden_count_ : count_; | |
15121 LookupCacheEntry** entries = set_property ? hidden_entries_ : entries_; | |
15122 for (int i = 0; i < count; i++) { | |
15123 LookupCacheEntry* entry = entries[i]; | |
15124 if (entry->map_ != map) continue; | |
15125 | |
15126 // Hit! Dive into prototype chain if needed | |
15127 Object* current = *obj; | |
15128 int depth = entry->depth_; | |
15129 for (int j = 0; j < depth; j++) { | |
15130 // XXX: Probably this is a fatal condition | |
15131 if (current == heap->null_value()) break; | |
15132 | |
15133 current = JSObject::cast(current)->GetPrototype(); | |
15134 } | |
15135 result->CopyFrom(&entry->result_, JSObject::cast(receiver)); | |
15136 | |
15137 return; | |
15138 } | |
15139 | |
15140 // Miss | |
15141 // Ecma-262 3rd 8.6.2.4 | |
15142 int depth = 0; | |
15143 if (set_property) { | |
15144 receiver->LocalLookup(*name, result, true); | |
15145 if (!result->IsFound()) { | |
15146 map->LookupTransition(JSObject::cast(*obj), | |
15147 *name, | |
15148 result); | |
15149 } | |
15150 } else { | |
15151 Object* current; | |
15152 for (current = *obj; | |
15153 current != heap->null_value(); | |
15154 current = JSObject::cast(current)->GetPrototype(), depth++) { | |
15155 JSReceiver::cast(current)->LocalLookup(*name, result, false); | |
15156 if (result->IsFound()) break; | |
15157 } | |
15158 if (current == heap->null_value()) result->NotFound(); | |
15159 } | |
15160 | |
15161 // If property wasn't found, or is not cacheable | |
15162 if (!result->IsFound() && result->IsCacheable()) return; | |
15163 | |
15164 // Cache is full, just return result | |
15165 if (count == kCacheEntryCount) return; | |
15166 | |
15167 // Insert new cache entry | |
15168 entries[count++] = new LookupCacheEntry(map, result, depth); | |
15169 | |
15170 // Update count | |
15171 if (set_property) { | |
15172 hidden_count_ = count; | |
15173 } else { | |
15174 count_ = count; | |
15175 } | |
15176 } | |
15177 | |
15178 | |
15179 MUST_USE_RESULT MaybeObject* LookupCache::GetProperty(Handle<Object> obj, | |
15180 Handle<Name> name) { | |
15181 PropertyAttributes attributes; | |
15182 LookupResult result(isolate_); | |
15183 Lookup(obj, name, &result); | |
15184 MaybeObject* value = obj->GetProperty(*obj, &result, *name, &attributes); | |
15185 ASSERT(attributes <= ABSENT); | |
15186 return value; | |
15187 } | |
15188 | |
15189 | |
15190 MUST_USE_RESULT MaybeObject* LookupCache::SetProperty(Handle<Object> obj, | |
15191 Handle<Name> name, | |
15192 Handle<Object> value) { | |
15193 ASSERT(obj->IsJSReceiver()); | |
15194 LookupResult result(isolate_); | |
15195 Lookup(obj, name, &result, true); | |
15196 JSReceiver* receiver = JSReceiver::cast(*obj); | |
15197 return receiver->SetProperty(&result, *name, *value, NONE, kNonStrictMode); | |
15198 } | |
15199 | |
15069 } } // namespace v8::internal | 15200 } } // namespace v8::internal |
OLD | NEW |