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(Isolate* isolate, Map* map, LookupResult* result, int depth) |
| 15073 : map_(Handle<Map>::cast(isolate->global_handles()->Create(map))), |
| 15074 result_(*result), |
| 15075 depth_(depth) { |
| 15076 } |
| 15077 |
| 15078 Handle<Map> map_; |
| 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(isolate_, 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 |