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 |