Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Unified Diff: src/objects-debug.cc

Issue 2140163002: Revert of making heap verification more aggressive (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects-debug.cc
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index fff4f3091c05f9e9c05af37a0abbd1d4d79aa0c7..13342ca36a405b187a862c54dca11a972d085f9e 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -100,14 +100,12 @@
break;
case JS_OBJECT_TYPE:
case JS_ERROR_TYPE:
+ case JS_ARGUMENTS_TYPE:
case JS_API_OBJECT_TYPE:
case JS_SPECIAL_API_OBJECT_TYPE:
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_PROMISE_TYPE:
JSObject::cast(this)->JSObjectVerify();
- break;
- case JS_ARGUMENTS_TYPE:
- JSArgumentsObject::cast(this)->JSArgumentsObjectVerify();
break;
case JS_GENERATOR_OBJECT_TYPE:
JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
@@ -248,9 +246,9 @@
template <class Traits>
void FixedTypedArray<Traits>::FixedTypedArrayVerify() {
- CHECK(IsHeapObject());
- CHECK(HeapObject::cast(this)->map()->instance_type() ==
- Traits::kInstanceType);
+ CHECK(IsHeapObject() &&
+ HeapObject::cast(this)->map()->instance_type() ==
+ Traits::kInstanceType);
if (base_pointer() == this) {
CHECK(external_pointer() ==
ExternalReference::fixed_typed_array_base_data_offset().address());
@@ -267,166 +265,76 @@
GetHeap()->one_pointer_filler_map();
}
-namespace {
-
-void VerifyFastProperties(JSReceiver* receiver) {
- // TODO(cbruni): JSProxy support for slow properties
- if (!receiver->IsJSObject()) return;
- Isolate* isolate = receiver->GetIsolate();
- Map* map = receiver->map();
- CHECK(!map->is_dictionary_map());
- JSObject* obj = JSObject::cast(receiver);
- int actual_unused_property_fields = map->GetInObjectProperties() +
- obj->properties()->length() -
- map->NextFreePropertyIndex();
- if (map->unused_property_fields() != actual_unused_property_fields) {
- // This could actually happen in the middle of StoreTransitionStub
- // when the new extended backing store is already set into the object and
- // the allocation of the MutableHeapNumber triggers GC (in this case map
- // is not updated yet).
- CHECK_EQ(map->unused_property_fields(),
- actual_unused_property_fields - JSObject::kFieldsAdded);
- }
- DescriptorArray* descriptors = map->instance_descriptors();
- for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
- if (descriptors->GetDetails(i).type() != DATA) continue;
- Representation r = descriptors->GetDetails(i).representation();
- FieldIndex index = FieldIndex::ForDescriptor(map, i);
- if (obj->IsUnboxedDoubleField(index)) {
- DCHECK(r.IsDouble());
- continue;
- }
- Object* value = obj->RawFastPropertyAt(index);
- if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
- if (value->IsUninitialized(isolate)) continue;
- if (r.IsSmi()) DCHECK(value->IsSmi());
- if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
- FieldType* field_type = descriptors->GetFieldType(i);
- bool type_is_none = field_type->IsNone();
- bool type_is_any = field_type->IsAny();
- if (r.IsNone()) {
- CHECK(type_is_none);
- } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
- // If allocation folding is off then GC could happen during inner
- // object literal creation and we will end up having and undefined
- // value that does not match the field type.
- CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
- (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
- }
- }
-}
-
-template <typename T>
-void VerifyDictionary(T* dict) {
- CHECK(dict->IsFixedArray());
- CHECK(dict->IsDictionary());
- int capacity = dict->Capacity();
- int nof = dict->NumberOfElements();
- int nod = dict->NumberOfDeletedElements();
- CHECK_LE(capacity, dict->length());
- CHECK_LE(nof, capacity);
- CHECK_LE(0, nof + nod);
- CHECK_LE(nof + nod, capacity);
-}
-
-void VerifySlowProperties(JSReceiver* obj) {
- Map* map = obj->map();
- CHECK(map->is_dictionary_map());
- CHECK_EQ(0, map->NumberOfOwnDescriptors());
- CHECK_EQ(0, map->unused_property_fields());
- CHECK_EQ(kInvalidEnumCacheSentinel, map->EnumLength());
- CHECK(obj->properties()->IsDictionary());
- // Kept in-object properties for sow-mode object need to be zapped:
- int nof_in_object_properties = map->GetInObjectProperties();
- if (nof_in_object_properties > 0) {
- JSObject* js_object = JSObject::cast(obj);
- Smi* zap_value = Smi::FromInt(0);
- for (int i = 0; i < nof_in_object_properties; i++) {
- FieldIndex index = FieldIndex::ForLoadByFieldIndex(map, i);
- Object* field = js_object->RawFastPropertyAt(index);
- CHECK_EQ(field, zap_value);
- }
- }
- if (obj->IsJSGlobalObject()) {
- VerifyDictionary(JSObject::cast(obj)->global_dictionary());
- } else {
- VerifyDictionary(obj->property_dictionary());
- }
-}
-
-void VerifyProperties(JSReceiver* obj) {
- obj->VerifyHeapPointer(obj->properties());
- if (obj->HasFastProperties()) {
- VerifyFastProperties(obj);
- } else {
- VerifySlowProperties(obj);
- }
-}
-
-void VerifyElements(JSObject* obj) {
- obj->VerifyHeapPointer(obj->elements());
+
+void JSObject::JSObjectVerify() {
+ VerifyHeapPointer(properties());
+ VerifyHeapPointer(elements());
+
+ if (HasSloppyArgumentsElements()) {
+ CHECK(this->elements()->IsFixedArray());
+ CHECK_GE(this->elements()->length(), 2);
+ }
+
+ if (HasFastProperties()) {
+ int actual_unused_property_fields = map()->GetInObjectProperties() +
+ properties()->length() -
+ map()->NextFreePropertyIndex();
+ if (map()->unused_property_fields() != actual_unused_property_fields) {
+ // This could actually happen in the middle of StoreTransitionStub
+ // when the new extended backing store is already set into the object and
+ // the allocation of the MutableHeapNumber triggers GC (in this case map
+ // is not updated yet).
+ CHECK_EQ(map()->unused_property_fields(),
+ actual_unused_property_fields - JSObject::kFieldsAdded);
+ }
+ DescriptorArray* descriptors = map()->instance_descriptors();
+ Isolate* isolate = GetIsolate();
+ for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
+ if (descriptors->GetDetails(i).type() == DATA) {
+ Representation r = descriptors->GetDetails(i).representation();
+ FieldIndex index = FieldIndex::ForDescriptor(map(), i);
+ if (IsUnboxedDoubleField(index)) {
+ DCHECK(r.IsDouble());
+ continue;
+ }
+ Object* value = RawFastPropertyAt(index);
+ if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
+ if (value->IsUninitialized(isolate)) continue;
+ if (r.IsSmi()) DCHECK(value->IsSmi());
+ if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
+ FieldType* field_type = descriptors->GetFieldType(i);
+ bool type_is_none = field_type->IsNone();
+ bool type_is_any = field_type->IsAny();
+ if (r.IsNone()) {
+ CHECK(type_is_none);
+ } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
+ // If allocation folding is off then GC could happen during inner
+ // object literal creation and we will end up having and undefined
+ // value that does not match the field type.
+ CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
+ (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
+ }
+ }
+ }
+ }
+
// If a GC was caused while constructing this object, the elements
// pointer may point to a one pointer filler map.
- if (!obj->ElementsAreSafeToExamine()) return;
- Map* map = obj->map();
- Heap* heap = obj->GetHeap();
- FixedArrayBase* elements = obj->elements();
- CHECK_EQ((map->has_fast_smi_or_object_elements() ||
- (elements == heap->empty_fixed_array()) ||
- obj->HasFastStringWrapperElements()),
- (elements->map() == heap->fixed_array_map() ||
- elements->map() == heap->fixed_cow_array_map()));
- CHECK_EQ(map->has_fast_object_elements(), obj->HasFastObjectElements());
-
- ElementsKind kind = obj->GetElementsKind();
- if (IsFastSmiOrObjectElementsKind(kind)) {
- CHECK(elements->map() == heap->fixed_array_map() ||
- elements->map() == heap->fixed_cow_array_map());
- } else if (IsFastDoubleElementsKind(kind)) {
- CHECK(elements->IsFixedDoubleArray() ||
- elements == heap->empty_fixed_array());
- } else if (kind == DICTIONARY_ELEMENTS) {
- CHECK(elements->IsSeededNumberDictionary());
- VerifyDictionary(SeededNumberDictionary::cast(elements));
- return;
- } else {
- CHECK(kind > DICTIONARY_ELEMENTS);
- }
- CHECK(!IsSloppyArgumentsElements(kind) ||
- (elements->IsFixedArray() && elements->length() >= 2));
-
- if (IsFastPackedElementsKind(kind)) {
- uint32_t length = elements->length();
- if (obj->IsJSArray()) {
- Object* number = JSArray::cast(obj)->length();
- if (number->IsSmi()) {
- length = Min(length, static_cast<uint32_t>(Smi::cast(number)->value()));
- }
- }
- if (kind == FAST_DOUBLE_ELEMENTS) {
- for (uint32_t i = 0; i < length; i++) {
- CHECK(!FixedDoubleArray::cast(elements)->is_the_hole(i));
- }
- } else {
- for (uint32_t i = 0; i < length; i++) {
- CHECK_NE(FixedArray::cast(elements)->get(i), heap->the_hole_value());
- }
- }
- }
-}
-
-} // namespace
-
-void JSObject::JSObjectVerify() {
- VerifyProperties(this);
- VerifyElements(this);
-}
+ if (ElementsAreSafeToExamine()) {
+ CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
+ (elements() == GetHeap()->empty_fixed_array()) ||
+ HasFastStringWrapperElements()),
+ (elements()->map() == GetHeap()->fixed_array_map() ||
+ elements()->map() == GetHeap()->fixed_cow_array_map()));
+ CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
+ }
+}
+
void Map::MapVerify() {
Heap* heap = GetHeap();
CHECK(!heap->InNewSpace(this));
- CHECK_LE(FIRST_TYPE, instance_type());
- CHECK_LE(instance_type(), LAST_TYPE);
+ CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
CHECK(instance_size() == kVariableSizeSentinel ||
(kPointerSize <= instance_size() &&
instance_size() < heap->Capacity()));
@@ -449,7 +357,6 @@
CHECK(instance_descriptors()->IsEmpty());
CHECK_EQ(0, unused_property_fields());
CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id());
- CHECK_EQ(kInvalidEnumCacheSentinel, EnumLength());
}
@@ -519,59 +426,6 @@
VerifyObjectField(kReceiverOffset);
VerifyObjectField(kOperandStackOffset);
VerifyObjectField(kContinuationOffset);
- JSObjectVerify();
-}
-
-namespace {
-
-void VerifyArgumentsParameterMap(FixedArray* elements) {
- Isolate* isolate = elements->GetIsolate();
- CHECK(elements->IsFixedArray());
- CHECK_GE(elements->length(), 2);
- HeapObject* context = HeapObject::cast(elements->get(0));
- HeapObject* arguments = HeapObject::cast(elements->get(1));
- // TODO(cbruni): fix arguments creation to be atomic.
- CHECK_IMPLIES(context->IsUndefined(isolate), arguments->IsUndefined(isolate));
- CHECK(context->IsUndefined(isolate) || context->IsContext());
- CHECK(arguments->IsUndefined(isolate) || arguments->IsFixedArray());
-}
-
-} // namespace
-
-void JSArgumentsObject::JSArgumentsObjectVerify() {
- VerifyObjectField(kLengthOffset);
- JSObjectVerify();
- Isolate* isolate = GetIsolate();
-
- if (isolate->bootstrapper()->IsActive()) return;
- Context* context = isolate->context();
- Object* constructor = map()->GetConstructor();
- if (constructor->IsJSFunction()) {
- context = JSFunction::cast(constructor)->context();
- }
- // TODO(cbruni): replace with NULL check once all hydrogren stubs manage to
- // set up the contexts properly.
- if (isolate->context()->IsSmi()) return;
- Context* native_context = context->native_context();
- if (map() == native_context->sloppy_arguments_map()) {
- // Sloppy arguments without aliased arguments has a normal elements backing
- // store which is already verified by JSObjectVerify() above.
- } else if (map() == native_context->fast_aliased_arguments_map()) {
- CHECK(HasFastArgumentsElements());
- FixedArray* elements = FixedArray::cast(this->elements());
- VerifyArgumentsParameterMap(FixedArray::cast(elements));
- CHECK_EQ(elements->map(), isolate->heap()->sloppy_arguments_elements_map());
- } else if (map() == native_context->slow_aliased_arguments_map()) {
- CHECK(HasSlowArgumentsElements());
- FixedArray* elements = FixedArray::cast(this->elements());
- VerifyArgumentsParameterMap(elements);
- VerifyDictionary(SeededNumberDictionary::cast(elements->get(1)));
- CHECK_EQ(elements->map(), isolate->heap()->sloppy_arguments_elements_map());
- } else if (map() == native_context->strict_arguments_map()) {
- CHECK(HasFastElements());
- } else {
- // TODO(cbruni): follow up on normalized argument maps.
- }
}
@@ -580,12 +434,10 @@
if (v->IsHeapObject()) {
VerifyHeapPointer(v);
}
- JSObjectVerify();
}
void JSDate::JSDateVerify() {
- JSObjectVerify();
if (value()->IsHeapObject()) {
VerifyHeapPointer(value());
}
@@ -635,7 +487,6 @@
void JSMessageObject::JSMessageObjectVerify() {
- JSObjectVerify();
CHECK(IsJSMessageObject());
VerifyObjectField(kStartPositionOffset);
VerifyObjectField(kEndPositionOffset);
@@ -694,7 +545,6 @@
void JSFunction::JSFunctionVerify() {
CHECK(IsJSFunction());
- JSObjectVerify();
VerifyObjectField(kPrototypeOrInitialMapOffset);
VerifyObjectField(kNextFunctionLinkOffset);
CHECK(code()->IsCode());
@@ -741,7 +591,6 @@
elements()->length() == 0) {
return;
}
- CHECK(!HasFastProperties());
JSObjectVerify();
}
@@ -845,7 +694,7 @@
} else if (obj->IsJSObject()) {
if (isolate->heap()->InNewSpace(obj)) {
ArrayList* list =
- isolate->heap()->weak_new_space_object_to_code_list();
+ GetIsolate()->heap()->weak_new_space_object_to_code_list();
bool found = false;
for (int i = 0; i < list->Length(); i += 2) {
WeakCell* obj_cell = WeakCell::cast(list->Get(i));
@@ -859,7 +708,7 @@
} else {
Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate);
DependentCode* dep =
- isolate->heap()->LookupWeakObjectToCodeDependency(key_obj);
+ GetIsolate()->heap()->LookupWeakObjectToCodeDependency(key_obj);
dep->Contains(DependentCode::kWeakCodeGroup, cell);
}
}
@@ -869,22 +718,17 @@
void JSArray::JSArrayVerify() {
- CHECK(IsJSArray());
JSObjectVerify();
Isolate* isolate = GetIsolate();
- // Allow undefined for not fully initialized JSArrays
- if (length()->IsUndefined(isolate)) {
- CHECK_EQ(FixedArray::cast(elements()),
- isolate->heap()->empty_fixed_array());
- return;
- }
- CHECK(length()->IsNumber());
+ CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
// If a GC was caused while constructing this array, the elements
// pointer may point to a one pointer filler map.
if (ElementsAreSafeToExamine()) {
- CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
- }
-}
+ CHECK(elements()->IsUndefined(isolate) || elements()->IsFixedArray() ||
+ elements()->IsFixedDoubleArray());
+ }
+}
+
void JSSet::JSSetVerify() {
CHECK(IsJSSet());
@@ -1452,8 +1296,7 @@
while (!old_it.done()) {
RelocInfo* rinfo = old_it.rinfo();
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- CHECK(!target->is_handler());
- CHECK(!target->is_inline_cache_stub());
+ CHECK(!target->is_handler() && !target->is_inline_cache_stub());
if (target == stack_check) break;
old_it.next();
}
@@ -1461,8 +1304,7 @@
while (!new_it.done()) {
RelocInfo* rinfo = new_it.rinfo();
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- CHECK(!target->is_handler());
- CHECK(!target->is_inline_cache_stub());
+ CHECK(!target->is_handler() && !target->is_inline_cache_stub());
if (target == stack_check) break;
new_it.next();
}
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698