diff options
Diffstat (limited to 'deps/v8/src/objects-debug.cc')
-rw-r--r-- | deps/v8/src/objects-debug.cc | 134 |
1 files changed, 95 insertions, 39 deletions
diff --git a/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc index ce075bf237..273bfa22e4 100644 --- a/deps/v8/src/objects-debug.cc +++ b/deps/v8/src/objects-debug.cc @@ -8,6 +8,7 @@ #include "src/bootstrapper.h" #include "src/disasm.h" #include "src/disassembler.h" +#include "src/elements.h" #include "src/field-type.h" #include "src/layout-descriptor.h" #include "src/macro-assembler.h" @@ -105,12 +106,14 @@ void HeapObject::HeapObjectVerify() { 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: JSObject::cast(this)->JSObjectVerify(); break; + case JS_ARGUMENTS_TYPE: + JSArgumentsObject::cast(this)->JSArgumentsObjectVerify(); + break; case JS_GENERATOR_OBJECT_TYPE: JSGeneratorObject::cast(this)->JSGeneratorObjectVerify(); break; @@ -162,6 +165,7 @@ void HeapObject::HeapObjectVerify() { case JS_MAP_ITERATOR_TYPE: JSMapIterator::cast(this)->JSMapIteratorVerify(); break; + case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE: case JS_FAST_ARRAY_KEY_ITERATOR_TYPE: case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE: @@ -326,30 +330,33 @@ void JSObject::JSObjectVerify() { VerifyHeapPointer(properties()); VerifyHeapPointer(elements()); - if (HasSloppyArgumentsElements()) { - CHECK(this->elements()->IsFixedArray()); - CHECK_GE(this->elements()->length(), 2); - } - + CHECK_IMPLIES(HasSloppyArgumentsElements(), IsJSArgumentsObject()); 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); + // There are two reasons why this can 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 while the map isn't updated yet. + // - deletion of the last property can leave additional backing store + // capacity behind. + CHECK_GT(actual_unused_property_fields, map()->unused_property_fields()); + int delta = + actual_unused_property_fields - map()->unused_property_fields(); + CHECK_EQ(0, delta % JSObject::kFieldsAdded); } DescriptorArray* descriptors = map()->instance_descriptors(); Isolate* isolate = GetIsolate(); + bool is_transitionable_fast_elements_kind = + IsTransitionableFastElementsKind(map()->elements_kind()); + for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() == kField) { DCHECK_EQ(kData, details.kind()); - Representation r = descriptors->GetDetails(i).representation(); + Representation r = details.representation(); FieldIndex index = FieldIndex::ForDescriptor(map(), i); if (IsUnboxedDoubleField(index)) { DCHECK(r.IsDouble()); @@ -372,6 +379,9 @@ void JSObject::JSObjectVerify() { CHECK(!field_type->NowStable() || field_type->NowContains(value) || (!FLAG_use_allocation_folding && value->IsUndefined(isolate))); } + CHECK_IMPLIES(is_transitionable_fast_elements_kind, + !Map::IsInplaceGeneralizableField(details.constness(), r, + field_type)); } } } @@ -428,13 +438,6 @@ void Map::VerifyOmittedMapChecks() { } -void TypeFeedbackInfo::TypeFeedbackInfoVerify() { - VerifyObjectField(kStorage1Offset); - VerifyObjectField(kStorage2Offset); - VerifyObjectField(kStorage3Offset); -} - - void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() { VerifySmiField(kAliasedContextSlot); } @@ -474,6 +477,78 @@ void TransitionArray::TransitionArrayVerify() { next_link()->IsTransitionArray()); } +void JSArgumentsObject::JSArgumentsObjectVerify() { + if (IsSloppyArgumentsElementsKind(GetElementsKind())) { + JSSloppyArgumentsObject::cast(this)->JSSloppyArgumentsObjectVerify(); + } + JSObjectVerify(); +} + +void JSSloppyArgumentsObject::JSSloppyArgumentsObjectVerify() { + Isolate* isolate = GetIsolate(); + if (!map()->is_dictionary_map()) VerifyObjectField(kCalleeOffset); + if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) || + isolate->IsInAnyContext(map(), + Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) || + isolate->IsInAnyContext(map(), + Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) { + VerifyObjectField(kLengthOffset); + VerifyObjectField(kCalleeOffset); + } + ElementsKind kind = GetElementsKind(); + CHECK(IsSloppyArgumentsElementsKind(kind)); + SloppyArgumentsElements::cast(elements()) + ->SloppyArgumentsElementsVerify(this); +} + +void SloppyArgumentsElements::SloppyArgumentsElementsVerify( + JSSloppyArgumentsObject* holder) { + Isolate* isolate = GetIsolate(); + FixedArrayVerify(); + // Abort verification if only partially initialized (can't use arguments() + // getter because it does FixedArray::cast()). + if (get(kArgumentsIndex)->IsUndefined(isolate)) return; + + ElementsKind kind = holder->GetElementsKind(); + bool is_fast = kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS; + CHECK(IsFixedArray()); + CHECK_GE(length(), 2); + CHECK_EQ(map(), isolate->heap()->sloppy_arguments_elements_map()); + Context* context_object = Context::cast(context()); + FixedArray* arg_elements = FixedArray::cast(arguments()); + if (arg_elements->length() == 0) { + CHECK(arg_elements == isolate->heap()->empty_fixed_array()); + return; + } + int nofMappedParameters = + length() - SloppyArgumentsElements::kParameterMapStart; + CHECK_LE(nofMappedParameters, context_object->length()); + CHECK_LE(nofMappedParameters, arg_elements->length()); + ElementsAccessor* accessor; + if (is_fast) { + accessor = ElementsAccessor::ForKind(FAST_HOLEY_ELEMENTS); + } else { + accessor = ElementsAccessor::ForKind(DICTIONARY_ELEMENTS); + } + for (int i = 0; i < nofMappedParameters; i++) { + // Verify that each context-mapped argument is either the hole or a valid + // Smi within context length range. + Object* mapped = get_mapped_entry(i); + if (mapped->IsTheHole(isolate)) { + // Slow sloppy arguments can be holey. + if (!is_fast) continue; + // Fast sloppy arguments elements are never holey. Either the element is + // context-mapped or present in the arguments elements. + CHECK(accessor->HasElement(holder, i, arg_elements)); + continue; + } + Object* value = context_object->get(Smi::cast(mapped)->value()); + CHECK(value->IsObject()); + // None of the context-mapped entries should exist in the arguments + // elements. + CHECK(!accessor->HasElement(holder, i, arg_elements)); + } +} void JSGeneratorObject::JSGeneratorObjectVerify() { // In an expression like "new g()", there can be a point where a generator @@ -637,7 +712,6 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() { VerifyObjectField(kFunctionIdentifierOffset); VerifyObjectField(kInstanceClassNameOffset); VerifyObjectField(kNameOffset); - VerifyObjectField(kOptimizedCodeMapOffset); VerifyObjectField(kOuterScopeInfoOffset); VerifyObjectField(kScopeInfoOffset); VerifyObjectField(kScriptOffset); @@ -1170,12 +1244,6 @@ void ContextExtension::ContextExtensionVerify() { VerifyObjectField(kExtensionOffset); } -void ConstantElementsPair::ConstantElementsPairVerify() { - CHECK(IsConstantElementsPair()); - VerifySmiField(kElementsKindOffset); - VerifyObjectField(kConstantValuesOffset); -} - void AccessorInfo::AccessorInfoVerify() { CHECK(IsAccessorInfo()); VerifyPointer(name()); @@ -1215,13 +1283,6 @@ void InterceptorInfo::InterceptorInfoVerify() { } -void CallHandlerInfo::CallHandlerInfoVerify() { - CHECK(IsCallHandlerInfo()); - VerifyPointer(callback()); - VerifyPointer(data()); -} - - void TemplateInfo::TemplateInfoVerify() { VerifyPointer(tag()); VerifyPointer(property_list()); @@ -1298,11 +1359,6 @@ void DebugInfo::DebugInfoVerify() { } -void BreakPointInfo::BreakPointInfoVerify() { - CHECK(IsBreakPointInfo()); - VerifyPointer(break_point_objects()); -} - void StackFrameInfo::StackFrameInfoVerify() { CHECK(IsStackFrameInfo()); VerifyPointer(script_name()); |