Report the per-isolate total size of scripts source.

As with other code size stats, this doesn't distinguish between live and
dead objects, and doesn't scan the young generation.

Also make ExternalString::is_short() const.

Bug: chromium:837659
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I72815edb719ba61d9727e226ff1da0fc4af22a24
Reviewed-on: https://chromium-review.googlesource.com/1032994
Commit-Queue: Benoit L <lizeb@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52955}
This commit is contained in:
Benoît Lizé 2018-05-02 14:46:45 +02:00 committed by Commit Bot
parent 5db17032a1
commit 1a0efd803a
9 changed files with 46 additions and 25 deletions

View File

@ -6593,10 +6593,12 @@ class V8_EXPORT HeapCodeStatistics {
HeapCodeStatistics(); HeapCodeStatistics();
size_t code_and_metadata_size() { return code_and_metadata_size_; } size_t code_and_metadata_size() { return code_and_metadata_size_; }
size_t bytecode_and_metadata_size() { return bytecode_and_metadata_size_; } size_t bytecode_and_metadata_size() { return bytecode_and_metadata_size_; }
size_t external_script_source_size() { return external_script_source_size_; }
private: private:
size_t code_and_metadata_size_; size_t code_and_metadata_size_;
size_t bytecode_and_metadata_size_; size_t bytecode_and_metadata_size_;
size_t external_script_source_size_;
friend class Isolate; friend class Isolate;
}; };

View File

@ -6026,7 +6026,9 @@ HeapObjectStatistics::HeapObjectStatistics()
object_size_(0) {} object_size_(0) {}
HeapCodeStatistics::HeapCodeStatistics() HeapCodeStatistics::HeapCodeStatistics()
: code_and_metadata_size_(0), bytecode_and_metadata_size_(0) {} : code_and_metadata_size_(0),
bytecode_and_metadata_size_(0),
external_script_source_size_(0) {}
bool v8::V8::InitializeICU(const char* icu_data_file) { bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file); return i::InitializeICU(icu_data_file);
@ -8461,6 +8463,8 @@ bool Isolate::GetHeapCodeAndMetadataStatistics(
code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size(); code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
code_statistics->bytecode_and_metadata_size_ = code_statistics->bytecode_and_metadata_size_ =
isolate->bytecode_and_metadata_size(); isolate->bytecode_and_metadata_size();
code_statistics->external_script_source_size_ =
isolate->external_script_source_size();
return true; return true;
} }

View File

@ -11,32 +11,41 @@ namespace internal {
// Record code statisitcs. // Record code statisitcs.
void CodeStatistics::RecordCodeAndMetadataStatistics(HeapObject* object, void CodeStatistics::RecordCodeAndMetadataStatistics(HeapObject* object,
Isolate* isolate) { Isolate* isolate) {
if (!object->IsAbstractCode()) { if (object->IsScript()) {
return; Script* script = Script::cast(object);
} // Log the size of external source code.
Object* source = script->source();
// Record code+metadata statisitcs. if (source->IsExternalString()) {
AbstractCode* abstract_code = AbstractCode::cast(object); ExternalString* external_source_string = ExternalString::cast(source);
int size = abstract_code->SizeIncludingMetadata(); int size = isolate->external_script_source_size();
if (abstract_code->IsCode()) { size += external_source_string->ExternalPayloadSize();
size += isolate->code_and_metadata_size(); isolate->set_external_script_source_size(size);
isolate->set_code_and_metadata_size(size); }
} else { } else if (object->IsAbstractCode()) {
size += isolate->bytecode_and_metadata_size(); // Record code+metadata statisitcs.
isolate->set_bytecode_and_metadata_size(size); AbstractCode* abstract_code = AbstractCode::cast(object);
} int size = abstract_code->SizeIncludingMetadata();
if (abstract_code->IsCode()) {
size += isolate->code_and_metadata_size();
isolate->set_code_and_metadata_size(size);
} else {
size += isolate->bytecode_and_metadata_size();
isolate->set_bytecode_and_metadata_size(size);
}
#ifdef DEBUG #ifdef DEBUG
// Record code kind and code comment statistics. // Record code kind and code comment statistics.
isolate->code_kind_statistics()[abstract_code->kind()] += isolate->code_kind_statistics()[abstract_code->kind()] +=
abstract_code->Size(); abstract_code->Size();
CodeStatistics::CollectCodeCommentStatistics(object, isolate); CodeStatistics::CollectCodeCommentStatistics(object, isolate);
#endif #endif
}
} }
void CodeStatistics::ResetCodeAndMetadataStatistics(Isolate* isolate) { void CodeStatistics::ResetCodeAndMetadataStatistics(Isolate* isolate) {
isolate->set_code_and_metadata_size(0); isolate->set_code_and_metadata_size(0);
isolate->set_bytecode_and_metadata_size(0); isolate->set_bytecode_and_metadata_size(0);
isolate->set_external_script_source_size(0);
#ifdef DEBUG #ifdef DEBUG
ResetCodeStatistics(isolate); ResetCodeStatistics(isolate);
#endif #endif

View File

@ -3485,6 +3485,7 @@ bool Heap::InvokeNearHeapLimitCallback() {
} }
void Heap::CollectCodeStatistics() { void Heap::CollectCodeStatistics() {
TRACE_EVENT0("v8", "Heap::CollectCodeStatistics");
CodeStatistics::ResetCodeAndMetadataStatistics(isolate()); CodeStatistics::ResetCodeAndMetadataStatistics(isolate());
// We do not look for code in new space, or map space. If code // We do not look for code in new space, or map space. If code
// somehow ends up in those spaces, we would miss it here. // somehow ends up in those spaces, we would miss it here.

View File

@ -644,10 +644,7 @@ void ObjectStatsCollectorImpl::RecordVirtualScriptDetails(Script* script) {
// The contents of external strings aren't on the heap, so we have to record // The contents of external strings aren't on the heap, so we have to record
// them manually. // them manually.
ExternalString* external_source_string = ExternalString::cast(source); ExternalString* external_source_string = ExternalString::cast(source);
size_t length_multiplier = external_source_string->IsTwoByteRepresentation() size_t off_heap_size = external_source_string->ExternalPayloadSize();
? kShortSize
: kCharSize;
size_t off_heap_size = external_source_string->length() * length_multiplier;
size_t on_heap_size = external_source_string->Size(); size_t on_heap_size = external_source_string->Size();
RecordVirtualObjectStats(script, external_source_string, RecordVirtualObjectStats(script, external_source_string,
ObjectStats::SCRIPT_SOURCE_EXTERNAL_TYPE, ObjectStats::SCRIPT_SOURCE_EXTERNAL_TYPE,

View File

@ -430,6 +430,7 @@ typedef std::vector<HeapObject*> DebugObjectCache;
V(const v8::StartupData*, snapshot_blob, nullptr) \ V(const v8::StartupData*, snapshot_blob, nullptr) \
V(int, code_and_metadata_size, 0) \ V(int, code_and_metadata_size, 0) \
V(int, bytecode_and_metadata_size, 0) \ V(int, bytecode_and_metadata_size, 0) \
V(int, external_script_source_size, 0) \
/* true if being profiled. Causes collection of extra compile info. */ \ /* true if being profiled. Causes collection of extra compile info. */ \
V(bool, is_profiling, false) \ V(bool, is_profiling, false) \
/* true if a trace is being formatted through Error.prepareStackTrace. */ \ /* true if a trace is being formatted through Error.prepareStackTrace. */ \

View File

@ -12089,6 +12089,11 @@ void SeqTwoByteString::clear_padding() {
SizeFor(length()) - data_size); SizeFor(length()) - data_size);
} }
int ExternalString::ExternalPayloadSize() const {
int length_multiplier = IsTwoByteRepresentation() ? kShortSize : kCharSize;
return length() * length_multiplier;
}
uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
// For array indexes mix the length into the hash as an array index could // For array indexes mix the length into the hash as an array index could
// be zero. // be zero.

View File

@ -529,7 +529,7 @@ HeapObject* ThinString::unchecked_actual() const {
return reinterpret_cast<HeapObject*>(READ_FIELD(this, kActualOffset)); return reinterpret_cast<HeapObject*>(READ_FIELD(this, kActualOffset));
} }
bool ExternalString::is_short() { bool ExternalString::is_short() const {
InstanceType type = map()->instance_type(); InstanceType type = map()->instance_type();
return (type & kShortExternalStringMask) == kShortExternalStringTag; return (type & kShortExternalStringMask) == kShortExternalStringTag;
} }

View File

@ -717,7 +717,9 @@ class ExternalString : public String {
static const int kSize = kResourceDataOffset + kPointerSize; static const int kSize = kResourceDataOffset + kPointerSize;
// Return whether external string is short (data pointer is not cached). // Return whether external string is short (data pointer is not cached).
inline bool is_short(); inline bool is_short() const;
// Size in bytes of the external payload.
int ExternalPayloadSize() const;
// Used in the serializer/deserializer. // Used in the serializer/deserializer.
inline Address resource_as_address(); inline Address resource_as_address();