Commit b57be748 authored by marja's avatar marja Committed by Commit bot

Revert of Fix memory leak caused by field type in descriptor array. (patchset...

Revert of Fix memory leak caused by field type in descriptor array. (patchset #3 id:40001 of https://codereview.chromium.org/955063002/)

Reason for revert:
Breaks test/mjsunit/debug-clearbreakpointgroup.js on arm64.debug.

Original issue's description:
> Fix memory leak caused by field type in descriptor array.
>
> When a field type is a map, it is wrapped in a weak cell upon storing to the descriptor array.
>
> Map::GetFieldType(i) does the unwrapping.
>
> BUG=v8:3877
> LOG=N
> TEST=cctest/test-heap/Regress3877
>
> Committed: https://crrev.com/77d3ae0e119893ac8d34ea6ca090cddd5bbf987e
> Cr-Commit-Position: refs/heads/master@{#26879}

TBR=verwaest@chromium.org,ulan@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3877

Review URL: https://codereview.chromium.org/960103003

Cr-Commit-Position: refs/heads/master@{#26883}
parent 6517181c
......@@ -3136,12 +3136,7 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) {
HeapType* DescriptorArray::GetFieldType(int descriptor_number) {
DCHECK(GetDetails(descriptor_number).location() == kField);
Object* value = GetValue(descriptor_number);
if (value->IsWeakCell()) {
if (WeakCell::cast(value)->cleared()) return HeapType::Any();
value = WeakCell::cast(value)->value();
}
return HeapType::cast(value);
return HeapType::cast(GetValue(descriptor_number));
}
......
......@@ -1704,12 +1704,6 @@ String* JSReceiver::constructor_name() {
}
static Handle<Object> WrapType(Handle<HeapType> type) {
if (type->IsClass()) return Map::WeakCellForMap(type->AsClass()->Map());
return type;
}
MaybeHandle<Map> Map::CopyWithField(Handle<Map> map,
Handle<Name> name,
Handle<HeapType> type,
......@@ -1735,10 +1729,7 @@ MaybeHandle<Map> Map::CopyWithField(Handle<Map> map,
type = HeapType::Any(isolate);
}
Handle<Object> wrapped_type(WrapType(type));
DataDescriptor new_field_desc(name, index, wrapped_type, attributes,
representation);
DataDescriptor new_field_desc(name, index, type, attributes, representation);
Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag);
int unused_property_fields = new_map->unused_property_fields() - 1;
if (unused_property_fields < 0) {
......@@ -2314,16 +2305,15 @@ Map* Map::FindFieldOwner(int descriptor) {
void Map::UpdateFieldType(int descriptor, Handle<Name> name,
Representation new_representation,
Handle<Object> new_wrapped_type) {
DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakCell());
Handle<HeapType> new_type) {
DisallowHeapAllocation no_allocation;
PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
if (details.type() != DATA) return;
if (HasTransitionArray()) {
TransitionArray* transitions = this->transitions();
for (int i = 0; i < transitions->number_of_transitions(); ++i) {
transitions->GetTarget(i)->UpdateFieldType(
descriptor, name, new_representation, new_wrapped_type);
transitions->GetTarget(i)
->UpdateFieldType(descriptor, name, new_representation, new_type);
}
}
// It is allowed to change representation here only from None to something.
......@@ -2331,9 +2321,9 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
details.representation().IsNone());
// Skip if already updated the shared descriptor.
if (instance_descriptors()->GetValue(descriptor) == *new_wrapped_type) return;
if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return;
DataDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor),
new_wrapped_type, details.attributes(), new_representation);
new_type, details.attributes(), new_representation);
instance_descriptors()->Replace(descriptor, &d);
}
......@@ -2381,10 +2371,8 @@ void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
PropertyDetails details = descriptors->GetDetails(modify_index);
Handle<Name> name(descriptors->GetKey(modify_index));
Handle<Object> wrapped_type(WrapType(new_field_type));
field_owner->UpdateFieldType(modify_index, name, new_representation,
wrapped_type);
new_field_type);
field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
isolate, DependentCode::kFieldTypeGroup);
......@@ -2776,8 +2764,7 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
next_field_type =
GeneralizeFieldType(target_field_type, old_field_type, isolate);
}
Handle<Object> wrapped_type(WrapType(next_field_type));
DataDescriptor d(target_key, current_offset, wrapped_type,
DataDescriptor d(target_key, current_offset, next_field_type,
next_attributes, next_representation);
current_offset += d.GetDetails().field_width_in_words();
new_descriptors->Set(i, &d);
......@@ -2845,10 +2832,8 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
next_field_type = old_field_type;
}
Handle<Object> wrapped_type(WrapType(next_field_type));
DataDescriptor d(old_key, current_offset, wrapped_type, next_attributes,
next_representation);
DataDescriptor d(old_key, current_offset, next_field_type,
next_attributes, next_representation);
current_offset += d.GetDetails().field_width_in_words();
new_descriptors->Set(i, &d);
} else {
......@@ -2979,41 +2964,33 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
if (!old_details.representation().fits_into(new_details.representation())) {
return MaybeHandle<Map>();
}
Object* new_value = new_descriptors->GetValue(i);
Object* old_value = old_descriptors->GetValue(i);
switch (new_details.type()) {
case DATA: {
HeapType* new_type = new_descriptors->GetFieldType(i);
PropertyType old_property_type = old_details.type();
if (old_property_type == DATA) {
HeapType* old_type = old_descriptors->GetFieldType(i);
if (!old_type->NowIs(new_type)) {
PropertyType old_type = old_details.type();
if (old_type == DATA) {
if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) {
return MaybeHandle<Map>();
}
} else {
DCHECK(old_property_type == DATA_CONSTANT);
Object* old_value = old_descriptors->GetValue(i);
if (!new_type->NowContains(old_value)) {
DCHECK(old_type == DATA_CONSTANT);
if (!HeapType::cast(new_value)->NowContains(old_value)) {
return MaybeHandle<Map>();
}
}
break;
}
case ACCESSOR: {
#ifdef DEBUG
HeapType* new_type = new_descriptors->GetFieldType(i);
DCHECK(HeapType::Any()->Is(new_type));
#endif
case ACCESSOR:
DCHECK(HeapType::Any()->Is(HeapType::cast(new_value)));
break;
}
case DATA_CONSTANT:
case ACCESSOR_CONSTANT: {
Object* old_value = old_descriptors->GetValue(i);
Object* new_value = new_descriptors->GetValue(i);
case ACCESSOR_CONSTANT:
if (old_details.location() == kField || old_value != new_value) {
return MaybeHandle<Map>();
}
break;
}
}
}
if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
......
......@@ -6443,12 +6443,9 @@ class Map: public HeapObject {
Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
// Update field type of the given descriptor to new representation and new
// type. The type must be prepared for storing in descriptor array:
// it must be either a simple type or a map wrapped in a weak cell.
void UpdateFieldType(int descriptor_number, Handle<Name> name,
Representation new_representation,
Handle<Object> new_wrapped_type);
Handle<HeapType> new_type);
void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
PropertyAttributes attributes);
......
......@@ -79,14 +79,10 @@ class DataDescriptor FINAL : public Descriptor {
PropertyAttributes attributes, Representation representation)
: Descriptor(key, HeapType::Any(key->GetIsolate()), attributes, DATA,
representation, field_index) {}
// The field type is either a simple type or a map wrapped in a weak cell.
DataDescriptor(Handle<Name> key, int field_index,
Handle<Object> wrapped_field_type,
DataDescriptor(Handle<Name> key, int field_index, Handle<HeapType> field_type,
PropertyAttributes attributes, Representation representation)
: Descriptor(key, wrapped_field_type, attributes, DATA, representation,
field_index) {
DCHECK(wrapped_field_type->IsSmi() || wrapped_field_type->IsWeakCell());
}
: Descriptor(key, field_type, attributes, DATA, representation,
field_index) {}
};
......
......@@ -5083,40 +5083,6 @@ TEST(NumberStringCacheSize) {
}
TEST(Regress3877) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
Factory* factory = isolate->factory();
HandleScope scope(isolate);
CompileRun("function cls() { this.x = 10; }");
Handle<WeakCell> weak_prototype;
{
HandleScope inner_scope(isolate);
v8::Local<v8::Value> result = CompileRun("cls.prototype");
Handle<JSObject> proto =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto));
}
CHECK(!weak_prototype->cleared());
CompileRun(
"var a = { };"
"a.x = new cls();"
"cls.prototype = null;");
for (int i = 0; i < 4; i++) {
heap->CollectAllGarbage(Heap::kNoGCFlags);
}
// The map of a.x keeps prototype alive
CHECK(!weak_prototype->cleared());
// Change the map of a.x and make the previous map garbage collectable.
CompileRun("a.x.__proto__ = {};");
for (int i = 0; i < 4; i++) {
heap->CollectAllGarbage(Heap::kNoGCFlags);
}
CHECK(weak_prototype->cleared());
}
#ifdef DEBUG
TEST(PathTracer) {
CcTest::InitializeVM();
......
......@@ -233,14 +233,12 @@ class Expectations {
representations_[descriptor])) {
return false;
}
Object* value = descriptors->GetValue(descriptor);
Object* expected_value = *values_[descriptor];
Object* value = descriptors->GetValue(descriptor);
switch (type) {
case DATA:
case ACCESSOR: {
HeapType* type = descriptors->GetFieldType(descriptor);
return HeapType::cast(expected_value)->Equals(type);
}
case ACCESSOR:
return HeapType::cast(expected_value)->Equals(HeapType::cast(value));
case DATA_CONSTANT:
return value == expected_value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment