diff --git a/src/heap/object-stats.cc b/src/heap/object-stats.cc index 9b21ad801f..079929e131 100644 --- a/src/heap/object-stats.cc +++ b/src/heap/object-stats.cc @@ -443,6 +443,11 @@ class ObjectStatsCollectorImpl { void RecordVirtualArrayBoilerplateDescription( ArrayBoilerplateDescription description); + + PtrComprCageBase cage_base() const { + return field_stats_collector_.cage_base(); + } + Heap* heap_; ObjectStats* stats_; MarkCompactCollector::NonAtomicMarkingState* marking_state_; @@ -488,7 +493,7 @@ void ObjectStatsCollectorImpl::RecordHashTableVirtualObjectStats( bool ObjectStatsCollectorImpl::RecordSimpleVirtualObjectStats( HeapObject parent, HeapObject obj, ObjectStats::VirtualInstanceType type) { - return RecordVirtualObjectStats(parent, obj, type, obj.Size(), + return RecordVirtualObjectStats(parent, obj, type, obj.Size(cage_base()), ObjectStats::kNoOverAllocation, kCheckCow); } @@ -711,7 +716,8 @@ void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails( MaybeObject raw_object = vector.Get(slot.WithOffset(i)); HeapObject object; if (raw_object->GetHeapObject(&object)) { - if (object.IsCell() || object.IsWeakFixedArray()) { + if (object.IsCell(cage_base()) || + object.IsWeakFixedArray(cage_base())) { RecordSimpleVirtualObjectStats( vector, object, ObjectStats::FEEDBACK_VECTOR_ENTRY_TYPE); } @@ -733,51 +739,55 @@ void ObjectStatsCollectorImpl::RecordVirtualFixedArrayDetails( void ObjectStatsCollectorImpl::CollectStatistics( HeapObject obj, Phase phase, CollectFieldStats collect_field_stats) { - Map map = obj.map(); + DisallowGarbageCollection no_gc; + Map map = obj.map(cage_base()); + InstanceType instance_type = map.instance_type(); switch (phase) { case kPhase1: - if (obj.IsFeedbackVector()) { + if (InstanceTypeChecker::IsFeedbackVector(instance_type)) { RecordVirtualFeedbackVectorDetails(FeedbackVector::cast(obj)); - } else if (obj.IsMap()) { + } else if (InstanceTypeChecker::IsMap(instance_type)) { RecordVirtualMapDetails(Map::cast(obj)); - } else if (obj.IsBytecodeArray()) { + } else if (InstanceTypeChecker::IsBytecodeArray(instance_type)) { RecordVirtualBytecodeArrayDetails(BytecodeArray::cast(obj)); - } else if (obj.IsCode()) { + } else if (InstanceTypeChecker::IsCode(instance_type)) { RecordVirtualCodeDetails(Code::cast(obj)); - } else if (obj.IsFunctionTemplateInfo()) { + } else if (InstanceTypeChecker::IsFunctionTemplateInfo(instance_type)) { RecordVirtualFunctionTemplateInfoDetails( FunctionTemplateInfo::cast(obj)); - } else if (obj.IsJSGlobalObject()) { + } else if (InstanceTypeChecker::IsJSGlobalObject(instance_type)) { RecordVirtualJSGlobalObjectDetails(JSGlobalObject::cast(obj)); - } else if (obj.IsJSObject()) { + } else if (InstanceTypeChecker::IsJSObject(instance_type)) { // This phase needs to come after RecordVirtualAllocationSiteDetails // to properly split among boilerplates. RecordVirtualJSObjectDetails(JSObject::cast(obj)); - } else if (obj.IsSharedFunctionInfo()) { + } else if (InstanceTypeChecker::IsSharedFunctionInfo(instance_type)) { RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo::cast(obj)); - } else if (obj.IsContext()) { + } else if (InstanceTypeChecker::IsContext(instance_type)) { RecordVirtualContext(Context::cast(obj)); - } else if (obj.IsScript()) { + } else if (InstanceTypeChecker::IsScript(instance_type)) { RecordVirtualScriptDetails(Script::cast(obj)); - } else if (obj.IsArrayBoilerplateDescription()) { + } else if (InstanceTypeChecker::IsArrayBoilerplateDescription( + instance_type)) { RecordVirtualArrayBoilerplateDescription( ArrayBoilerplateDescription::cast(obj)); - } else if (obj.IsFixedArrayExact()) { + } else if (InstanceTypeChecker::IsFixedArrayExact(instance_type)) { // Has to go last as it triggers too eagerly. RecordVirtualFixedArrayDetails(FixedArray::cast(obj)); } break; case kPhase2: - if (obj.IsExternalString()) { + if (InstanceTypeChecker::IsExternalString(instance_type)) { // This has to be in Phase2 to avoid conflicting with recording Script // sources. We still want to run RecordObjectStats after though. RecordVirtualExternalStringDetails(ExternalString::cast(obj)); } size_t over_allocated = ObjectStats::kNoOverAllocation; - if (obj.IsJSObject()) { + if (InstanceTypeChecker::IsJSObject(instance_type)) { over_allocated = map.instance_size() - map.UsedInstanceSize(); } - RecordObjectStats(obj, map.instance_type(), obj.Size(), over_allocated); + RecordObjectStats(obj, instance_type, obj.Size(cage_base()), + over_allocated); if (collect_field_stats == CollectFieldStats::kYes) { field_stats_collector_.RecordStats(obj); } @@ -788,7 +798,7 @@ void ObjectStatsCollectorImpl::CollectStatistics( void ObjectStatsCollectorImpl::CollectGlobalStatistics() { // Iterate boilerplates first to disambiguate them from regular JS objects. Object list = heap_->allocation_sites_list(); - while (list.IsAllocationSite()) { + while (list.IsAllocationSite(cage_base())) { AllocationSite site = AllocationSite::cast(list); RecordVirtualAllocationSiteDetails(site); list = site.weak_next(); @@ -829,7 +839,7 @@ bool ObjectStatsCollectorImpl::CanRecordFixedArray(FixedArrayBase array) { } bool ObjectStatsCollectorImpl::IsCowArray(FixedArrayBase array) { - return array.map() == ReadOnlyRoots(heap_).fixed_cow_array_map(); + return array.map(cage_base()) == ReadOnlyRoots(heap_).fixed_cow_array_map(); } bool ObjectStatsCollectorImpl::SameLiveness(HeapObject obj1, HeapObject obj2) { @@ -868,7 +878,7 @@ void ObjectStatsCollectorImpl::RecordVirtualMapDetails(Map map) { // This will be logged as MAP_TYPE in Phase2. } - DescriptorArray array = map.instance_descriptors(isolate()); + DescriptorArray array = map.instance_descriptors(cage_base()); if (map.owns_descriptors() && array != ReadOnlyRoots(heap_).empty_descriptor_array()) { // Generally DescriptorArrays have their own instance type already @@ -891,10 +901,10 @@ void ObjectStatsCollectorImpl::RecordVirtualMapDetails(Map map) { } if (map.is_prototype_map()) { - if (map.prototype_info().IsPrototypeInfo()) { + if (map.prototype_info().IsPrototypeInfo(cage_base())) { PrototypeInfo info = PrototypeInfo::cast(map.prototype_info()); Object users = info.prototype_users(); - if (users.IsWeakFixedArray()) { + if (users.IsWeakFixedArray(cage_base())) { RecordSimpleVirtualObjectStats(map, WeakArrayList::cast(users), ObjectStats::PROTOTYPE_USERS_TYPE); } @@ -909,7 +919,7 @@ void ObjectStatsCollectorImpl::RecordVirtualScriptDetails(Script script) { // Log the size of external source code. Object raw_source = script.source(); - if (raw_source.IsExternalString()) { + if (raw_source.IsExternalString(cage_base())) { // The contents of external strings aren't on the heap, so we have to record // them manually. The on-heap String object is recorded indepentendely in // the normal pass. @@ -922,7 +932,7 @@ void ObjectStatsCollectorImpl::RecordVirtualScriptDetails(Script script) { ? ObjectStats::SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE : ObjectStats::SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE, off_heap_size); - } else if (raw_source.IsString()) { + } else if (raw_source.IsString(cage_base())) { String source = String::cast(raw_source); RecordSimpleVirtualObjectStats( script, source, @@ -940,7 +950,7 @@ void ObjectStatsCollectorImpl::RecordVirtualExternalStringDetails( size_t off_heap_size = string.ExternalPayloadSize(); RecordExternalResourceStats( resource, - string.IsOneByteRepresentation() + string.IsOneByteRepresentation(cage_base()) ? ObjectStats::STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE : ObjectStats::STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE, off_heap_size); @@ -967,7 +977,7 @@ void ObjectStatsCollectorImpl:: HeapObject parent, HeapObject object, ObjectStats::VirtualInstanceType type) { if (!RecordSimpleVirtualObjectStats(parent, object, type)) return; - if (object.IsFixedArrayExact()) { + if (object.IsFixedArrayExact(cage_base())) { FixedArray array = FixedArray::cast(object); for (int i = 0; i < array.length(); i++) { Object entry = array.get(i); @@ -988,7 +998,7 @@ void ObjectStatsCollectorImpl::RecordVirtualBytecodeArrayDetails( FixedArray constant_pool = FixedArray::cast(bytecode.constant_pool()); for (int i = 0; i < constant_pool.length(); i++) { Object entry = constant_pool.get(i); - if (entry.IsFixedArrayExact()) { + if (entry.IsFixedArrayExact(cage_base())) { RecordVirtualObjectsForConstantPoolOrEmbeddedObjects( constant_pool, HeapObject::cast(entry), ObjectStats::EMBEDDED_OBJECT_TYPE); @@ -1041,11 +1051,10 @@ void ObjectStatsCollectorImpl::RecordVirtualCodeDetails(Code code) { } } int const mode_mask = RelocInfo::EmbeddedObjectModeMask(); - PtrComprCageBase cage_base(heap_->isolate()); for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode())); - Object target = it.rinfo()->target_object(cage_base); - if (target.IsFixedArrayExact()) { + Object target = it.rinfo()->target_object(cage_base()); + if (target.IsFixedArrayExact(cage_base())) { RecordVirtualObjectsForConstantPoolOrEmbeddedObjects( code, HeapObject::cast(target), ObjectStats::EMBEDDED_OBJECT_TYPE); } @@ -1055,7 +1064,7 @@ void ObjectStatsCollectorImpl::RecordVirtualCodeDetails(Code code) { void ObjectStatsCollectorImpl::RecordVirtualContext(Context context) { if (context.IsNativeContext()) { RecordObjectStats(context, NATIVE_CONTEXT_TYPE, context.Size()); - if (context.retained_maps().IsWeakArrayList()) { + if (context.retained_maps().IsWeakArrayList(cage_base())) { RecordSimpleVirtualObjectStats( context, WeakArrayList::cast(context.retained_maps()), ObjectStats::RETAINED_MAPS_TYPE); diff --git a/test/mjsunit/debugPrint.js b/test/mjsunit/debugPrint.js index 682a41463c..e67d10f4db 100644 --- a/test/mjsunit/debugPrint.js +++ b/test/mjsunit/debugPrint.js @@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --allow-natives-syntax +// Test various debug flags + +// Flags: --allow-natives-syntax --trace-gc-object-stats --gc-global +// Flags: --trace-zone-stats --expose-gc --trace-gc var largeArray = []; largeArray[0xFFFF00] = 123; @@ -25,7 +28,22 @@ function slowSloppyArguments2(a, b) { return arguments; } +let proto_obj = { fn1() { return 1 } } +let obj_with_enum_cache = { + __proto__: proto_obj, + a: 1, + b: 2, + c: "c" +}; +for (let k in obj_with_enum_cache) { + // do something + obj_with_enum_cache.a += obj_with_enum_cache.fn1(); +} + + +let string_1 = "aasdfasdfasdfasdf asd fa sdf asdf as dfa sdf asd f" +let string_2 = "aasdfasdfasdfasdf asd fa sdf UC16\u2028asdf as dfa sdf asd f" var objects = [ this, true, false, null, undefined, @@ -33,8 +51,10 @@ var objects = [ 9007199254740991.0, 9007199254740991.0 + 10, -9007199254740992.0, -9007199254740992.0 - 10, Infinity, -Infinity, NaN, - "aasdfasdfasdfasdf", "a"+"b", + string_1, string_1+"b", string_1.slice(1), + string_2, string_2+"b", string_2.slice(1), {}, {1:1}, {a:1}, {1:1, 2:2}, Object.create(null), + obj_with_enum_cache, [], [{}, {}], [1, 1, 1], [1.1, 1.1, 1.1, 1.1, 2], largeArray, new Proxy({},{}), new Date(), new String(" a"), @@ -53,3 +73,6 @@ var objects = [ ]; for (var o of objects) %DebugPrint(o); + +// Trigger some gcs to trigger heap and zone stats +for (let i = 0; i <= 4; i++) gc();