Chromium Code Reviews| 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/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 Factory* factory = isolate->factory(); | 119 Factory* factory = isolate->factory(); |
| 120 return factory->LookupSingleCharacterStringFromCode( | 120 return factory->LookupSingleCharacterStringFromCode( |
| 121 String::Flatten(str)->Get(index)); | 121 String::Flatten(str)->Get(index)); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Fall back to GetObjectProperty. | 125 // Fall back to GetObjectProperty. |
| 126 return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj); | 126 return Runtime::GetObjectProperty(isolate, receiver_obj, key_obj); |
| 127 } | 127 } |
| 128 | 128 |
| 129 namespace { | |
| 130 | |
| 131 bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver, | |
| 132 Handle<Object> raw_key) { | |
| 133 Map* map = receiver->map(); | |
| 134 if (map->instance_type() <= LAST_SPECIAL_RECEIVER_TYPE) return false; | |
|
Igor Sheludko
2017/05/03 14:39:25
map->IsSpecialReceiverMap()
Jakob Kummerow
2017/05/03 14:49:27
Done.
| |
| 135 if (!raw_key->IsUniqueName()) return false; | |
| 136 Handle<Name> key = Handle<Name>::cast(raw_key); | |
| 137 // This implements a special case for fast property deletion: when the | |
| 138 // last property in an object is deleted, then instead of normalizing | |
| 139 // the properties, we can undo the last map transition, with a few | |
| 140 // prerequisites: | |
| 141 // (1) The current map must not be marked stable. Otherwise there could be | |
| 142 // optimized code that depends on the assumption that no object that reached | |
| 143 // this map transitions away from it (without triggering the "deoptimize | |
| 144 // dependent code" mechanism). | |
| 145 if (map->is_stable()) return false; | |
| 146 // (2) The property to be deleted must be the last property. | |
| 147 int nof = map->NumberOfOwnDescriptors(); | |
| 148 if (nof == 0) return false; | |
| 149 int descriptor = nof - 1; | |
| 150 DescriptorArray* descriptors = map->instance_descriptors(); | |
| 151 if (descriptors->GetKey(descriptor) != *key) return false; | |
| 152 // (3) The property to be deleted must be deletable. | |
| 153 PropertyDetails details = descriptors->GetDetails(descriptor); | |
| 154 if (!details.IsConfigurable()) return false; | |
| 155 // (4) The map must have a back pointer. | |
| 156 Object* backpointer = map->GetBackPointer(); | |
| 157 if (!backpointer->IsMap()) return false; | |
| 158 // (5) The last transition must hvae been caused by adding a property | |
|
Igor Sheludko
2017/05/03 14:39:25
s/hvae/have/
Jakob Kummerow
2017/05/03 14:49:27
Done.
| |
| 159 // (and not any kind of special transition). | |
| 160 if (Map::cast(backpointer)->NumberOfOwnDescriptors() != nof - 1) return false; | |
| 161 | |
| 162 // Preconditions successful, perform the map rollback! | |
| 163 // Zap the property to avoid keeping objects alive. Zapping is not necessary | |
| 164 // for properties stored in the descriptor array. | |
| 165 if (details.location() == kField) { | |
| 166 Object* filler = isolate->heap()->one_pointer_filler_map(); | |
| 167 FieldIndex index = FieldIndex::ForPropertyIndex(map, details.field_index()); | |
| 168 JSObject::cast(*receiver)->RawFastPropertyAtPut(index, filler); | |
| 169 // We must clear any recorded slot for the deleted property, because | |
| 170 // subsequent object modifications might put a raw double there. | |
| 171 // Slot clearing is the reason why this entire function cannot currently | |
| 172 // be implemented in the DeleteProperty stub. | |
| 173 if (index.is_inobject() && !map->IsUnboxedDoubleField(index)) { | |
|
Igor Sheludko
2017/05/03 14:39:25
"index.is_inobject() &&" is not necessary because
Jakob Kummerow
2017/05/03 14:49:27
Nope, it's necessary. For out-of-object fields, "I
Igor Sheludko
2017/05/03 14:53:26
Acknowledged.
| |
| 174 isolate->heap()->ClearRecordedSlot( | |
| 175 *receiver, HeapObject::RawField(*receiver, index.offset())); | |
| 176 } | |
| 177 } | |
| 178 receiver->synchronized_set_map(Map::cast(backpointer)); | |
| 179 return true; | |
| 180 } | |
| 181 | |
| 182 } // namespace | |
| 129 | 183 |
| 130 Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate, | 184 Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate, |
| 131 Handle<JSReceiver> receiver, | 185 Handle<JSReceiver> receiver, |
| 132 Handle<Object> key, | 186 Handle<Object> key, |
| 133 LanguageMode language_mode) { | 187 LanguageMode language_mode) { |
| 188 if (DeleteObjectPropertyFast(isolate, receiver, key)) return Just(true); | |
| 189 | |
| 134 bool success = false; | 190 bool success = false; |
| 135 LookupIterator it = LookupIterator::PropertyOrElement( | 191 LookupIterator it = LookupIterator::PropertyOrElement( |
| 136 isolate, receiver, key, &success, LookupIterator::OWN); | 192 isolate, receiver, key, &success, LookupIterator::OWN); |
| 137 if (!success) return Nothing<bool>(); | 193 if (!success) return Nothing<bool>(); |
| 138 | 194 |
| 139 return JSReceiver::DeleteProperty(&it, language_mode); | 195 return JSReceiver::DeleteProperty(&it, language_mode); |
| 140 } | 196 } |
| 141 | 197 |
| 142 // ES6 19.1.3.2 | 198 // ES6 19.1.3.2 |
| 143 RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { | 199 RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { |
| (...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 // While iteration alone may not have observable side-effects, calling | 1093 // While iteration alone may not have observable side-effects, calling |
| 1038 // toNumber on an object will. Make sure the arg is not an array of objects. | 1094 // toNumber on an object will. Make sure the arg is not an array of objects. |
| 1039 ElementsKind kind = JSObject::cast(*obj)->GetElementsKind(); | 1095 ElementsKind kind = JSObject::cast(*obj)->GetElementsKind(); |
| 1040 if (!IsFastNumberElementsKind(kind)) return isolate->heap()->ToBoolean(false); | 1096 if (!IsFastNumberElementsKind(kind)) return isolate->heap()->ToBoolean(false); |
| 1041 | 1097 |
| 1042 return isolate->heap()->ToBoolean(!obj->IterationHasObservableEffects()); | 1098 return isolate->heap()->ToBoolean(!obj->IterationHasObservableEffects()); |
| 1043 } | 1099 } |
| 1044 | 1100 |
| 1045 } // namespace internal | 1101 } // namespace internal |
| 1046 } // namespace v8 | 1102 } // namespace v8 |
| OLD | NEW |