| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 void LookupIterator::ReloadPropertyInformation() { | 87 void LookupIterator::ReloadPropertyInformation() { |
| 88 state_ = BEFORE_PROPERTY; | 88 state_ = BEFORE_PROPERTY; |
| 89 state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked()); | 89 state_ = LookupInHolder(*holder_map_, *maybe_holder_.ToHandleChecked()); |
| 90 DCHECK(IsFound() || holder_map_->is_dictionary_map()); | 90 DCHECK(IsFound() || holder_map_->is_dictionary_map()); |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { | 94 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { |
| 95 DCHECK(state_ == DATA || state_ == ACCESSOR); | 95 DCHECK(state_ == DATA || state_ == ACCESSOR); |
| 96 DCHECK(HolderIsReceiverOrHiddenPrototype()); | 96 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
| 97 if (property_encoding_ == DICTIONARY) return; | 97 if (holder_map_->is_dictionary_map()) return; |
| 98 holder_map_ = | 98 holder_map_ = |
| 99 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); | 99 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); |
| 100 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); | 100 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); |
| 101 ReloadPropertyInformation(); | 101 ReloadPropertyInformation(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 | 104 |
| 105 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, | 105 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, |
| 106 PropertyAttributes attributes) { | 106 PropertyAttributes attributes) { |
| 107 DCHECK(state_ == DATA || state_ == ACCESSOR); | 107 DCHECK(state_ == DATA || state_ == ACCESSOR); |
| 108 DCHECK(HolderIsReceiverOrHiddenPrototype()); | 108 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
| 109 Handle<JSObject> holder = GetHolder<JSObject>(); | 109 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 110 if (property_encoding_ != DICTIONARY) { | 110 if (holder_map_->is_dictionary_map()) { |
| 111 PropertyDetails details(attributes, NORMAL, 0); |
| 112 JSObject::SetNormalizedProperty(holder, name(), value, details); |
| 113 } else { |
| 111 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(), | 114 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(), |
| 112 attributes); | 115 attributes); |
| 113 JSObject::MigrateToMap(holder, holder_map_); | 116 JSObject::MigrateToMap(holder, holder_map_); |
| 114 } | 117 } |
| 115 | 118 |
| 116 if (holder_map_->is_dictionary_map()) { | |
| 117 PropertyDetails details(attributes, NORMAL, 0); | |
| 118 JSObject::SetNormalizedProperty(holder, name(), value, details); | |
| 119 } | |
| 120 | |
| 121 ReloadPropertyInformation(); | 119 ReloadPropertyInformation(); |
| 122 } | 120 } |
| 123 | 121 |
| 124 | 122 |
| 125 void LookupIterator::PrepareTransitionToDataProperty( | 123 void LookupIterator::PrepareTransitionToDataProperty( |
| 126 Handle<Object> value, PropertyAttributes attributes, | 124 Handle<Object> value, PropertyAttributes attributes, |
| 127 Object::StoreFromKeyed store_mode) { | 125 Object::StoreFromKeyed store_mode) { |
| 128 if (state_ == TRANSITION) return; | 126 if (state_ == TRANSITION) return; |
| 129 DCHECK(state_ != LookupIterator::ACCESSOR || | 127 DCHECK(state_ != LookupIterator::ACCESSOR || |
| 130 GetAccessors()->IsDeclaredAccessorInfo()); | 128 GetAccessors()->IsDeclaredAccessorInfo()); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 DCHECK(!current->IsJSProxy()); | 223 DCHECK(!current->IsJSProxy()); |
| 226 iter.Advance(); | 224 iter.Advance(); |
| 227 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); | 225 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); |
| 228 return false; | 226 return false; |
| 229 } | 227 } |
| 230 | 228 |
| 231 | 229 |
| 232 Handle<Object> LookupIterator::FetchValue() const { | 230 Handle<Object> LookupIterator::FetchValue() const { |
| 233 Object* result = NULL; | 231 Object* result = NULL; |
| 234 Handle<JSObject> holder = GetHolder<JSObject>(); | 232 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 235 switch (property_encoding_) { | 233 if (holder_map_->is_dictionary_map()) { |
| 236 case DICTIONARY: | 234 result = holder->property_dictionary()->ValueAt(number_); |
| 237 result = holder->property_dictionary()->ValueAt(number_); | 235 if (holder_map_->IsGlobalObjectMap()) { |
| 238 if (holder->IsGlobalObject()) { | 236 result = PropertyCell::cast(result)->value(); |
| 239 result = PropertyCell::cast(result)->value(); | 237 } |
| 240 } | 238 } else if (property_details_.type() == v8::internal::FIELD) { |
| 241 break; | 239 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); |
| 242 case DESCRIPTOR: | 240 return JSObject::FastPropertyAt(holder, property_details_.representation(), |
| 243 if (property_details_.type() == v8::internal::FIELD) { | 241 field_index); |
| 244 FieldIndex field_index = | 242 } else { |
| 245 FieldIndex::ForDescriptor(*holder_map_, number_); | 243 result = holder_map_->instance_descriptors()->GetValue(number_); |
| 246 return JSObject::FastPropertyAt( | |
| 247 holder, property_details_.representation(), field_index); | |
| 248 } | |
| 249 result = holder_map_->instance_descriptors()->GetValue(number_); | |
| 250 } | 244 } |
| 251 return handle(result, isolate_); | 245 return handle(result, isolate_); |
| 252 } | 246 } |
| 253 | 247 |
| 254 | 248 |
| 255 int LookupIterator::GetConstantIndex() const { | 249 int LookupIterator::GetConstantIndex() const { |
| 256 DCHECK(has_property_); | 250 DCHECK(has_property_); |
| 257 DCHECK_EQ(DESCRIPTOR, property_encoding_); | 251 DCHECK(!holder_map_->is_dictionary_map()); |
| 258 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); | 252 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); |
| 259 return descriptor_number(); | 253 return descriptor_number(); |
| 260 } | 254 } |
| 261 | 255 |
| 262 | 256 |
| 263 FieldIndex LookupIterator::GetFieldIndex() const { | 257 FieldIndex LookupIterator::GetFieldIndex() const { |
| 264 DCHECK(has_property_); | 258 DCHECK(has_property_); |
| 265 DCHECK_EQ(DESCRIPTOR, property_encoding_); | 259 DCHECK(!holder_map_->is_dictionary_map()); |
| 266 DCHECK_EQ(v8::internal::FIELD, property_details_.type()); | 260 DCHECK_EQ(v8::internal::FIELD, property_details_.type()); |
| 267 int index = | 261 int index = |
| 268 holder_map()->instance_descriptors()->GetFieldIndex(descriptor_number()); | 262 holder_map_->instance_descriptors()->GetFieldIndex(descriptor_number()); |
| 269 bool is_double = representation().IsDouble(); | 263 bool is_double = representation().IsDouble(); |
| 270 return FieldIndex::ForPropertyIndex(*holder_map(), index, is_double); | 264 return FieldIndex::ForPropertyIndex(*holder_map_, index, is_double); |
| 271 } | 265 } |
| 272 | 266 |
| 273 | 267 |
| 274 Handle<HeapType> LookupIterator::GetFieldType() const { | 268 Handle<HeapType> LookupIterator::GetFieldType() const { |
| 275 DCHECK(has_property_); | 269 DCHECK(has_property_); |
| 276 DCHECK_EQ(DESCRIPTOR, property_encoding_); | 270 DCHECK(!holder_map_->is_dictionary_map()); |
| 277 DCHECK_EQ(v8::internal::FIELD, property_details_.type()); | 271 DCHECK_EQ(v8::internal::FIELD, property_details_.type()); |
| 278 return handle( | 272 return handle( |
| 279 holder_map()->instance_descriptors()->GetFieldType(descriptor_number()), | 273 holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), |
| 280 isolate_); | 274 isolate_); |
| 281 } | 275 } |
| 282 | 276 |
| 283 | 277 |
| 284 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { | 278 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { |
| 285 Handle<JSObject> holder = GetHolder<JSObject>(); | 279 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 286 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 280 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
| 287 Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); | 281 Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); |
| 288 return Handle<PropertyCell>(PropertyCell::cast(value)); | 282 return Handle<PropertyCell>(PropertyCell::cast(value)); |
| 289 } | 283 } |
| 290 | 284 |
| 291 | 285 |
| 292 Handle<Object> LookupIterator::GetAccessors() const { | 286 Handle<Object> LookupIterator::GetAccessors() const { |
| 293 DCHECK_EQ(ACCESSOR, state_); | 287 DCHECK_EQ(ACCESSOR, state_); |
| 294 return FetchValue(); | 288 return FetchValue(); |
| 295 } | 289 } |
| 296 | 290 |
| 297 | 291 |
| 298 Handle<Object> LookupIterator::GetDataValue() const { | 292 Handle<Object> LookupIterator::GetDataValue() const { |
| 299 DCHECK_EQ(DATA, state_); | 293 DCHECK_EQ(DATA, state_); |
| 300 Handle<Object> value = FetchValue(); | 294 Handle<Object> value = FetchValue(); |
| 301 return value; | 295 return value; |
| 302 } | 296 } |
| 303 | 297 |
| 304 | 298 |
| 305 void LookupIterator::WriteDataValue(Handle<Object> value) { | 299 void LookupIterator::WriteDataValue(Handle<Object> value) { |
| 306 DCHECK(is_guaranteed_to_have_holder()); | 300 DCHECK(is_guaranteed_to_have_holder()); |
| 307 DCHECK_EQ(DATA, state_); | 301 DCHECK_EQ(DATA, state_); |
| 308 Handle<JSObject> holder = GetHolder<JSObject>(); | 302 Handle<JSObject> holder = GetHolder<JSObject>(); |
| 309 if (property_encoding_ == DICTIONARY) { | 303 if (holder_map_->is_dictionary_map()) { |
| 310 NameDictionary* property_dictionary = holder->property_dictionary(); | 304 NameDictionary* property_dictionary = holder->property_dictionary(); |
| 311 if (holder->IsGlobalObject()) { | 305 if (holder->IsGlobalObject()) { |
| 312 Handle<PropertyCell> cell( | 306 Handle<PropertyCell> cell( |
| 313 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); | 307 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); |
| 314 PropertyCell::SetValueInferType(cell, value); | 308 PropertyCell::SetValueInferType(cell, value); |
| 315 } else { | 309 } else { |
| 316 property_dictionary->ValueAtPut(dictionary_entry(), *value); | 310 property_dictionary->ValueAtPut(dictionary_entry(), *value); |
| 317 } | 311 } |
| 318 } else if (property_details_.type() == v8::internal::FIELD) { | 312 } else if (property_details_.type() == v8::internal::FIELD) { |
| 319 holder->WriteToField(descriptor_number(), *value); | 313 holder->WriteToField(descriptor_number(), *value); |
| 320 } else { | 314 } else { |
| 321 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); | 315 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); |
| 322 } | 316 } |
| 323 } | 317 } |
| 324 | 318 |
| 325 | 319 |
| 326 void LookupIterator::InternalizeName() { | 320 void LookupIterator::InternalizeName() { |
| 327 if (name_->IsUniqueName()) return; | 321 if (name_->IsUniqueName()) return; |
| 328 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); | 322 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); |
| 329 } | 323 } |
| 330 } } // namespace v8::internal | 324 } } // namespace v8::internal |
| OLD | NEW |