| 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/v8.h" | 5 #include "src/v8.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/lookup.h" | 9 #include "src/lookup.h" |
| 10 #include "src/lookup-inl.h" | 10 #include "src/lookup-inl.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 JSReceiver* maybe_holder = NextHolder(map); | 28 JSReceiver* maybe_holder = NextHolder(map); |
| 29 if (maybe_holder == NULL) break; | 29 if (maybe_holder == NULL) break; |
| 30 holder = maybe_holder; | 30 holder = maybe_holder; |
| 31 map = holder->map(); | 31 map = holder->map(); |
| 32 state_ = LookupInHolder(map); | 32 state_ = LookupInHolder(map); |
| 33 } | 33 } |
| 34 | 34 |
| 35 // Either was found in the receiver, or the receiver has no prototype. | 35 // Either was found in the receiver, or the receiver has no prototype. |
| 36 if (holder == NULL) return; | 36 if (holder == NULL) return; |
| 37 | 37 |
| 38 maybe_holder_ = handle(holder); | 38 maybe_holder_ = handle(holder, isolate_); |
| 39 holder_map_ = handle(map); | 39 holder_map_ = handle(map, isolate_); |
| 40 } | 40 } |
| 41 | 41 |
| 42 | 42 |
| 43 Handle<JSReceiver> LookupIterator::GetRoot() const { | 43 Handle<JSReceiver> LookupIterator::GetRoot() const { |
| 44 Handle<Object> receiver = GetReceiver(); | 44 Handle<Object> receiver = GetReceiver(); |
| 45 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver); | 45 if (receiver->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver); |
| 46 Handle<Object> root = | 46 Handle<Object> root = |
| 47 handle(receiver->GetRootMap(isolate_)->prototype(), isolate_); | 47 handle(receiver->GetRootMap(isolate_)->prototype(), isolate_); |
| 48 CHECK(!root->IsNull()); | 48 CHECK(!root->IsNull()); |
| 49 return Handle<JSReceiver>::cast(root); | 49 return Handle<JSReceiver>::cast(root); |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 Handle<Map> LookupIterator::GetReceiverMap() const { | 53 Handle<Map> LookupIterator::GetReceiverMap() const { |
| 54 Handle<Object> receiver = GetReceiver(); | 54 Handle<Object> receiver = GetReceiver(); |
| 55 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map(); | 55 if (receiver->IsNumber()) return isolate_->factory()->heap_number_map(); |
| 56 return handle(Handle<HeapObject>::cast(receiver)->map()); | 56 return handle(Handle<HeapObject>::cast(receiver)->map(), isolate_); |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 Handle<JSObject> LookupIterator::GetStoreTarget() const { | 60 Handle<JSObject> LookupIterator::GetStoreTarget() const { |
| 61 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); | 61 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); |
| 62 | 62 |
| 63 if (receiver->IsJSGlobalProxy()) { | 63 if (receiver->IsJSGlobalProxy()) { |
| 64 PrototypeIterator iter(isolate(), receiver); | 64 PrototypeIterator iter(isolate(), receiver); |
| 65 if (iter.IsAtEnd()) return receiver; | 65 if (iter.IsAtEnd()) return receiver; |
| 66 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); | 66 return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 // handled via a trap. Adding properties to primitive values is not | 177 // handled via a trap. Adding properties to primitive values is not |
| 178 // observable. | 178 // observable. |
| 179 Handle<JSObject> receiver = GetStoreTarget(); | 179 Handle<JSObject> receiver = GetStoreTarget(); |
| 180 | 180 |
| 181 if (!name().is_identical_to(isolate()->factory()->hidden_string()) && | 181 if (!name().is_identical_to(isolate()->factory()->hidden_string()) && |
| 182 !receiver->map()->is_extensible()) { | 182 !receiver->map()->is_extensible()) { |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 | 185 |
| 186 transition_map_ = Map::TransitionToDataProperty( | 186 transition_map_ = Map::TransitionToDataProperty( |
| 187 handle(receiver->map()), name_, value, attributes, store_mode); | 187 handle(receiver->map(), isolate_), name_, value, attributes, store_mode); |
| 188 state_ = TRANSITION; | 188 state_ = TRANSITION; |
| 189 } | 189 } |
| 190 | 190 |
| 191 | 191 |
| 192 void LookupIterator::ApplyTransitionToDataProperty() { | 192 void LookupIterator::ApplyTransitionToDataProperty() { |
| 193 DCHECK_EQ(TRANSITION, state_); | 193 DCHECK_EQ(TRANSITION, state_); |
| 194 | 194 |
| 195 Handle<JSObject> receiver = GetStoreTarget(); | 195 Handle<JSObject> receiver = GetStoreTarget(); |
| 196 maybe_holder_ = receiver; | 196 maybe_holder_ = receiver; |
| 197 holder_map_ = transition_map_; | 197 holder_map_ = transition_map_; |
| 198 JSObject::MigrateToMap(receiver, holder_map_); | 198 JSObject::MigrateToMap(receiver, holder_map_); |
| 199 ReloadPropertyInformation(); | 199 ReloadPropertyInformation(); |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 void LookupIterator::TransitionToAccessorProperty( | 203 void LookupIterator::TransitionToAccessorProperty( |
| 204 AccessorComponent component, Handle<Object> accessor, | 204 AccessorComponent component, Handle<Object> accessor, |
| 205 PropertyAttributes attributes) { | 205 PropertyAttributes attributes) { |
| 206 DCHECK(!accessor->IsNull()); | 206 DCHECK(!accessor->IsNull()); |
| 207 // Can only be called when the receiver is a JSObject. JSProxy has to be | 207 // Can only be called when the receiver is a JSObject. JSProxy has to be |
| 208 // handled via a trap. Adding properties to primitive values is not | 208 // handled via a trap. Adding properties to primitive values is not |
| 209 // observable. | 209 // observable. |
| 210 Handle<JSObject> receiver = GetStoreTarget(); | 210 Handle<JSObject> receiver = GetStoreTarget(); |
| 211 maybe_holder_ = receiver; | 211 maybe_holder_ = receiver; |
| 212 holder_map_ = Map::TransitionToAccessorProperty( | 212 holder_map_ = |
| 213 handle(receiver->map()), name_, component, accessor, attributes); | 213 Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_), |
| 214 name_, component, accessor, attributes); |
| 214 JSObject::MigrateToMap(receiver, holder_map_); | 215 JSObject::MigrateToMap(receiver, holder_map_); |
| 215 | 216 |
| 216 ReloadPropertyInformation(); | 217 ReloadPropertyInformation(); |
| 217 | 218 |
| 218 if (!holder_map_->is_dictionary_map()) return; | 219 if (!holder_map_->is_dictionary_map()) return; |
| 219 | 220 |
| 220 // We have to deoptimize since accesses to data properties may have been | 221 // We have to deoptimize since accesses to data properties may have been |
| 221 // inlined without a corresponding map-check. | 222 // inlined without a corresponding map-check. |
| 222 if (holder_map_->IsGlobalObjectMap()) { | 223 if (holder_map_->IsGlobalObjectMap()) { |
| 223 Deoptimizer::DeoptimizeGlobalObject(*receiver); | 224 Deoptimizer::DeoptimizeGlobalObject(*receiver); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 236 pair = AccessorPair::Copy(pair); | 237 pair = AccessorPair::Copy(pair); |
| 237 pair->set(component, *accessor); | 238 pair->set(component, *accessor); |
| 238 } | 239 } |
| 239 } else { | 240 } else { |
| 240 pair = isolate()->factory()->NewAccessorPair(); | 241 pair = isolate()->factory()->NewAccessorPair(); |
| 241 pair->set(component, *accessor); | 242 pair->set(component, *accessor); |
| 242 } | 243 } |
| 243 JSObject::SetNormalizedProperty(receiver, name_, pair, details); | 244 JSObject::SetNormalizedProperty(receiver, name_, pair, details); |
| 244 | 245 |
| 245 JSObject::ReoptimizeIfPrototype(receiver); | 246 JSObject::ReoptimizeIfPrototype(receiver); |
| 246 holder_map_ = handle(receiver->map()); | 247 holder_map_ = handle(receiver->map(), isolate_); |
| 247 ReloadPropertyInformation(); | 248 ReloadPropertyInformation(); |
| 248 } | 249 } |
| 249 | 250 |
| 250 | 251 |
| 251 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { | 252 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { |
| 252 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); | 253 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); |
| 253 // Optimization that only works if configuration_ is not mutable. | 254 // Optimization that only works if configuration_ is not mutable. |
| 254 if (!check_derived()) return true; | 255 if (!check_derived()) return true; |
| 255 DisallowHeapAllocation no_gc; | 256 DisallowHeapAllocation no_gc; |
| 256 Handle<Object> receiver = GetReceiver(); | 257 Handle<Object> receiver = GetReceiver(); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); | 377 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); |
| 377 } | 378 } |
| 378 } | 379 } |
| 379 | 380 |
| 380 | 381 |
| 381 void LookupIterator::InternalizeName() { | 382 void LookupIterator::InternalizeName() { |
| 382 if (name_->IsUniqueName()) return; | 383 if (name_->IsUniqueName()) return; |
| 383 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); | 384 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); |
| 384 } | 385 } |
| 385 } } // namespace v8::internal | 386 } } // namespace v8::internal |
| OLD | NEW |