Index: src/builtins/builtins-internal-gen.cc |
diff --git a/src/builtins/builtins-internal-gen.cc b/src/builtins/builtins-internal-gen.cc |
index 321afa0d03c5e633562d766238ec2e038960b2f4..8ba2873c25758f0fb205320a5599fb53af9d5c99 100644 |
--- a/src/builtins/builtins-internal-gen.cc |
+++ b/src/builtins/builtins-internal-gen.cc |
@@ -169,84 +169,6 @@ class DeletePropertyBaseAssembler : public CodeStubAssembler { |
explicit DeletePropertyBaseAssembler(compiler::CodeAssemblerState* state) |
: CodeStubAssembler(state) {} |
- void DeleteFastProperty(Node* receiver, Node* receiver_map, Node* properties, |
- Node* name, Label* dont_delete, Label* not_found, |
- Label* slow) { |
- // This builtin implements a special case for fast property deletion: |
- // when the last property in an object is deleted, then instead of |
- // normalizing the properties, we can undo the last map transition, |
- // with a few prerequisites: |
- // (1) The current map must not be marked stable. Otherwise there could |
- // be optimized code that depends on the assumption that no object that |
- // reached this map transitions away from it (without triggering the |
- // "deoptimize dependent code" mechanism). |
- Node* bitfield3 = LoadMapBitField3(receiver_map); |
- GotoIfNot(IsSetWord32<Map::IsUnstable>(bitfield3), slow); |
- // (2) The property to be deleted must be the last property. |
- Node* descriptors = LoadMapDescriptors(receiver_map); |
- Node* nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3); |
- GotoIf(Word32Equal(nof, Int32Constant(0)), not_found); |
- Node* descriptor_number = Int32Sub(nof, Int32Constant(1)); |
- Node* key_index = DescriptorArrayToKeyIndex(descriptor_number); |
- Node* actual_key = LoadFixedArrayElement(descriptors, key_index); |
- // TODO(jkummerow): We could implement full descriptor search in order |
- // to avoid the runtime call for deleting nonexistent properties, but |
- // that's probably a rare case. |
- GotoIf(WordNotEqual(actual_key, name), slow); |
- // (3) The property to be deleted must be deletable. |
- Node* details = |
- LoadDetailsByKeyIndex<DescriptorArray>(descriptors, key_index); |
- GotoIf(IsSetWord32(details, PropertyDetails::kAttributesDontDeleteMask), |
- dont_delete); |
- // (4) The map must have a back pointer. |
- Node* backpointer = |
- LoadObjectField(receiver_map, Map::kConstructorOrBackPointerOffset); |
- GotoIfNot(IsMap(backpointer), slow); |
- // (5) The last transition must have been caused by adding a property |
- // (and not any kind of special transition). |
- Node* previous_nof = DecodeWord32<Map::NumberOfOwnDescriptorsBits>( |
- LoadMapBitField3(backpointer)); |
- GotoIfNot(Word32Equal(previous_nof, descriptor_number), slow); |
- |
- // Preconditions successful, perform the map rollback! |
- // Zap the property to avoid keeping objects alive. |
- // Zapping is not necessary for properties stored in the descriptor array. |
- Label zapping_done(this); |
- GotoIf(Word32NotEqual(DecodeWord32<PropertyDetails::LocationField>(details), |
- Int32Constant(kField)), |
- &zapping_done); |
- Node* field_index = |
- DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details); |
- Node* inobject_properties = LoadMapInobjectProperties(receiver_map); |
- Label inobject(this), backing_store(this); |
- // Due to inobject slack tracking, a field currently within the object |
- // could later be between objects. Use the one pointer filler map for |
- // zapping the deleted field to make this safe. |
- Node* filler = LoadRoot(Heap::kOnePointerFillerMapRootIndex); |
- DCHECK(Heap::RootIsImmortalImmovable(Heap::kOnePointerFillerMapRootIndex)); |
- Branch(UintPtrLessThan(field_index, inobject_properties), &inobject, |
- &backing_store); |
- BIND(&inobject); |
- { |
- Node* field_offset = |
- IntPtrMul(IntPtrSub(LoadMapInstanceSize(receiver_map), |
- IntPtrSub(inobject_properties, field_index)), |
- IntPtrConstant(kPointerSize)); |
- StoreObjectFieldNoWriteBarrier(receiver, field_offset, filler); |
- Goto(&zapping_done); |
- } |
- BIND(&backing_store); |
- { |
- Node* backing_store_index = IntPtrSub(field_index, inobject_properties); |
- StoreFixedArrayElement(properties, backing_store_index, filler, |
- SKIP_WRITE_BARRIER); |
- Goto(&zapping_done); |
- } |
- BIND(&zapping_done); |
- StoreMap(receiver, backpointer); |
- Return(TrueConstant()); |
- } |
- |
void DeleteDictionaryProperty(Node* receiver, Node* properties, Node* name, |
Node* context, Label* dont_delete, |
Label* notfound) { |
@@ -328,8 +250,9 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { |
Node* properties_map = LoadMap(properties); |
GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
&dictionary); |
- DeleteFastProperty(receiver, receiver_map, properties, unique, &dont_delete, |
- &if_notfound, &slow); |
+ // Fast properties need to clear recorded slots, which can only be done |
+ // in C++. |
+ Goto(&slow); |
BIND(&dictionary); |
{ |