OLD | NEW |
1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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/builtins/builtins-utils-gen.h" | 5 #include "src/builtins/builtins-utils-gen.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" |
8 #include "src/macro-assembler.h" | 8 #include "src/macro-assembler.h" |
9 #include "src/runtime/runtime.h" | 9 #include "src/runtime/runtime.h" |
10 | 10 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 // Allocate in old space (or large object space). | 157 // Allocate in old space (or large object space). |
158 TailCallRuntime(Runtime::kNewArgumentsElements, NoContextConstant(), | 158 TailCallRuntime(Runtime::kNewArgumentsElements, NoContextConstant(), |
159 BitcastWordToTagged(frame), SmiFromWord(length)); | 159 BitcastWordToTagged(frame), SmiFromWord(length)); |
160 } | 160 } |
161 } | 161 } |
162 | 162 |
163 TF_BUILTIN(ReturnReceiver, CodeStubAssembler) { | 163 TF_BUILTIN(ReturnReceiver, CodeStubAssembler) { |
164 Return(Parameter(Descriptor::kReceiver)); | 164 Return(Parameter(Descriptor::kReceiver)); |
165 } | 165 } |
166 | 166 |
| 167 class DeletePropertyBaseAssembler : public CodeStubAssembler { |
| 168 public: |
| 169 explicit DeletePropertyBaseAssembler(compiler::CodeAssemblerState* state) |
| 170 : CodeStubAssembler(state) {} |
| 171 |
| 172 void DeleteDictionaryProperty(Node* receiver, Node* properties, Node* name, |
| 173 Node* context, Label* dont_delete, |
| 174 Label* notfound) { |
| 175 VARIABLE(var_name_index, MachineType::PointerRepresentation()); |
| 176 Label dictionary_found(this, &var_name_index); |
| 177 NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found, |
| 178 &var_name_index, notfound); |
| 179 |
| 180 BIND(&dictionary_found); |
| 181 Node* key_index = var_name_index.value(); |
| 182 Node* details = |
| 183 LoadDetailsByKeyIndex<NameDictionary>(properties, key_index); |
| 184 GotoIf(IsSetWord32(details, PropertyDetails::kAttributesDontDeleteMask), |
| 185 dont_delete); |
| 186 // Overwrite the entry itself (see NameDictionary::SetEntry). |
| 187 Node* filler = TheHoleConstant(); |
| 188 DCHECK(Heap::RootIsImmortalImmovable(Heap::kTheHoleValueRootIndex)); |
| 189 StoreFixedArrayElement(properties, key_index, filler, SKIP_WRITE_BARRIER); |
| 190 StoreValueByKeyIndex<NameDictionary>(properties, key_index, filler, |
| 191 SKIP_WRITE_BARRIER); |
| 192 StoreDetailsByKeyIndex<NameDictionary>(properties, key_index, |
| 193 SmiConstant(Smi::kZero)); |
| 194 |
| 195 // Update bookkeeping information (see NameDictionary::ElementRemoved). |
| 196 Node* nof = GetNumberOfElements<NameDictionary>(properties); |
| 197 Node* new_nof = SmiSub(nof, SmiConstant(1)); |
| 198 SetNumberOfElements<NameDictionary>(properties, new_nof); |
| 199 Node* num_deleted = GetNumberOfDeletedElements<NameDictionary>(properties); |
| 200 Node* new_deleted = SmiAdd(num_deleted, SmiConstant(1)); |
| 201 SetNumberOfDeletedElements<NameDictionary>(properties, new_deleted); |
| 202 |
| 203 // Shrink the dictionary if necessary (see NameDictionary::Shrink). |
| 204 Label shrinking_done(this); |
| 205 Node* capacity = GetCapacity<NameDictionary>(properties); |
| 206 GotoIf(SmiGreaterThan(new_nof, SmiShr(capacity, 2)), &shrinking_done); |
| 207 GotoIf(SmiLessThan(new_nof, SmiConstant(16)), &shrinking_done); |
| 208 CallRuntime(Runtime::kShrinkPropertyDictionary, context, receiver, name); |
| 209 Goto(&shrinking_done); |
| 210 BIND(&shrinking_done); |
| 211 |
| 212 Return(TrueConstant()); |
| 213 } |
| 214 }; |
| 215 |
| 216 TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { |
| 217 Node* receiver = Parameter(Descriptor::kObject); |
| 218 Node* key = Parameter(Descriptor::kKey); |
| 219 Node* language_mode = Parameter(Descriptor::kLanguageMode); |
| 220 Node* context = Parameter(Descriptor::kContext); |
| 221 |
| 222 VARIABLE(var_index, MachineType::PointerRepresentation()); |
| 223 VARIABLE(var_unique, MachineRepresentation::kTagged, key); |
| 224 Label if_index(this), if_unique_name(this), if_notunique(this), |
| 225 if_notfound(this), slow(this); |
| 226 |
| 227 GotoIf(TaggedIsSmi(receiver), &slow); |
| 228 Node* receiver_map = LoadMap(receiver); |
| 229 Node* instance_type = LoadMapInstanceType(receiver_map); |
| 230 GotoIf(Int32LessThanOrEqual(instance_type, |
| 231 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
| 232 &slow); |
| 233 TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique, &slow, |
| 234 &if_notunique); |
| 235 |
| 236 BIND(&if_index); |
| 237 { |
| 238 Comment("integer index"); |
| 239 Goto(&slow); // TODO(jkummerow): Implement more smarts here. |
| 240 } |
| 241 |
| 242 BIND(&if_unique_name); |
| 243 { |
| 244 Comment("key is unique name"); |
| 245 Node* unique = var_unique.value(); |
| 246 CheckForAssociatedProtector(unique, &slow); |
| 247 |
| 248 Label dictionary(this), dont_delete(this); |
| 249 Node* properties = LoadProperties(receiver); |
| 250 Node* properties_map = LoadMap(properties); |
| 251 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
| 252 &dictionary); |
| 253 // TODO(jkummerow): Implement support for fast properties? |
| 254 Goto(&slow); |
| 255 |
| 256 BIND(&dictionary); |
| 257 { |
| 258 DeleteDictionaryProperty(receiver, properties, unique, context, |
| 259 &dont_delete, &if_notfound); |
| 260 } |
| 261 |
| 262 BIND(&dont_delete); |
| 263 { |
| 264 STATIC_ASSERT(LANGUAGE_END == 2); |
| 265 GotoIf(SmiNotEqual(language_mode, SmiConstant(SLOPPY)), &slow); |
| 266 Return(FalseConstant()); |
| 267 } |
| 268 } |
| 269 |
| 270 BIND(&if_notunique); |
| 271 { |
| 272 // If the string was not found in the string table, then no object can |
| 273 // have a property with that name. |
| 274 TryInternalizeString(key, &if_index, &var_index, &if_unique_name, |
| 275 &var_unique, &if_notfound, &slow); |
| 276 } |
| 277 |
| 278 BIND(&if_notfound); |
| 279 Return(TrueConstant()); |
| 280 |
| 281 BIND(&slow); |
| 282 { |
| 283 TailCallRuntime(Runtime::kDeleteProperty, context, receiver, key, |
| 284 language_mode); |
| 285 } |
| 286 } |
| 287 |
167 } // namespace internal | 288 } // namespace internal |
168 } // namespace v8 | 289 } // namespace v8 |
OLD | NEW |