OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/lookup.h" | 5 #include "src/lookup.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/elements.h" | 9 #include "src/elements.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 DCHECK(state_ == DATA || state_ == ACCESSOR); | 159 DCHECK(state_ == DATA || state_ == ACCESSOR); |
160 DCHECK(HolderIsReceiverOrHiddenPrototype()); | 160 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
161 | 161 |
162 Handle<JSObject> holder = GetHolder<JSObject>(); | 162 Handle<JSObject> holder = GetHolder<JSObject>(); |
163 | 163 |
164 if (IsElement()) { | 164 if (IsElement()) { |
165 ElementsKind kind = holder_map_->elements_kind(); | 165 ElementsKind kind = holder_map_->elements_kind(); |
166 ElementsKind to = value->OptimalElementsKind(); | 166 ElementsKind to = value->OptimalElementsKind(); |
167 if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to); | 167 if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to); |
168 to = GetMoreGeneralElementsKind(kind, to); | 168 to = GetMoreGeneralElementsKind(kind, to); |
169 JSObject::TransitionElementsKind(holder, to); | 169 |
170 holder_map_ = handle(holder->map(), isolate_); | 170 if (kind != to) { |
| 171 JSObject::TransitionElementsKind(holder, to); |
| 172 holder_map_ = handle(holder->map(), isolate_); |
| 173 } |
171 | 174 |
172 // Copy the backing store if it is copy-on-write. | 175 // Copy the backing store if it is copy-on-write. |
173 if (IsFastSmiOrObjectElementsKind(to)) { | 176 if (IsFastSmiOrObjectElementsKind(to)) { |
174 JSObject::EnsureWritableFastElements(holder); | 177 JSObject::EnsureWritableFastElements(holder); |
175 } | 178 } |
176 | 179 |
| 180 if (kind == to) return; |
| 181 |
177 } else { | 182 } else { |
178 if (holder_map_->is_dictionary_map()) return; | 183 if (holder_map_->is_dictionary_map()) return; |
179 holder_map_ = | 184 holder_map_ = |
180 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); | 185 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); |
| 186 |
| 187 if (holder->map() == *holder_map_) { |
| 188 // Update the property details if the representation was None. |
| 189 if (representation().IsNone()) { |
| 190 property_details_ = holder_map_->instance_descriptors()->GetDetails( |
| 191 descriptor_number()); |
| 192 } |
| 193 return; |
| 194 } |
181 } | 195 } |
182 | 196 |
183 JSObject::MigrateToMap(holder, holder_map_); | 197 JSObject::MigrateToMap(holder, holder_map_); |
184 ReloadPropertyInformation(); | 198 ReloadPropertyInformation(); |
185 } | 199 } |
186 | 200 |
187 | 201 |
188 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, | 202 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, |
189 PropertyAttributes attributes) { | 203 PropertyAttributes attributes) { |
190 DCHECK(state_ == DATA || state_ == ACCESSOR); | 204 DCHECK(state_ == DATA || state_ == ACCESSOR); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 270 } |
257 } | 271 } |
258 | 272 |
259 | 273 |
260 void LookupIterator::ApplyTransitionToDataProperty() { | 274 void LookupIterator::ApplyTransitionToDataProperty() { |
261 DCHECK_EQ(TRANSITION, state_); | 275 DCHECK_EQ(TRANSITION, state_); |
262 | 276 |
263 Handle<JSObject> receiver = GetStoreTarget(); | 277 Handle<JSObject> receiver = GetStoreTarget(); |
264 if (receiver->IsJSGlobalObject()) return; | 278 if (receiver->IsJSGlobalObject()) return; |
265 holder_ = receiver; | 279 holder_ = receiver; |
266 holder_map_ = transition_map(); | 280 Handle<Map> transition = transition_map(); |
| 281 bool simple_transition = transition->GetBackPointer() == receiver->map(); |
| 282 holder_map_ = transition; |
267 JSObject::MigrateToMap(receiver, holder_map_); | 283 JSObject::MigrateToMap(receiver, holder_map_); |
268 ReloadPropertyInformation(); | 284 |
| 285 if (simple_transition) { |
| 286 int number = transition->LastAdded(); |
| 287 number_ = static_cast<uint32_t>(number); |
| 288 property_details_ = transition->GetLastDescriptorDetails(); |
| 289 state_ = DATA; |
| 290 } else { |
| 291 ReloadPropertyInformation(); |
| 292 } |
269 } | 293 } |
270 | 294 |
271 | 295 |
272 void LookupIterator::Delete() { | 296 void LookupIterator::Delete() { |
273 Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_); | 297 Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_); |
274 if (IsElement()) { | 298 if (IsElement()) { |
275 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 299 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
276 ElementsAccessor* accessor = object->GetElementsAccessor(); | 300 ElementsAccessor* accessor = object->GetElementsAccessor(); |
277 accessor->Delete(object, number_); | 301 accessor->Delete(object, number_); |
278 } else { | 302 } else { |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 // Fall through. | 693 // Fall through. |
670 default: | 694 default: |
671 return NOT_FOUND; | 695 return NOT_FOUND; |
672 } | 696 } |
673 UNREACHABLE(); | 697 UNREACHABLE(); |
674 return state_; | 698 return state_; |
675 } | 699 } |
676 | 700 |
677 } // namespace internal | 701 } // namespace internal |
678 } // namespace v8 | 702 } // namespace v8 |
OLD | NEW |