Commit e56bd9c3 authored by yangguo's avatar yangguo Committed by Commit bot

[serializer] print use count of external references.

R=peria@chromium.org, vogelheim@chromium.org
BUG=chromium:617892
NOPRESUBMIT=true

Review-Url: https://codereview.chromium.org/2495213003
Cr-Commit-Position: refs/heads/master@{#40979}
parent aed65cb4
......@@ -559,6 +559,10 @@ StartupData SnapshotCreator::CreateBlob(
}
data->contexts_.Clear();
#ifdef DEBUG
i::ExternalReferenceTable::instance(isolate)->ResetCount();
#endif // DEBUG
i::StartupSerializer startup_serializer(isolate, function_code_handling);
startup_serializer.SerializeStrongReferences();
......@@ -572,6 +576,13 @@ StartupData SnapshotCreator::CreateBlob(
}
startup_serializer.SerializeWeakReferencesAndDeferred();
#ifdef DEBUG
if (i::FLAG_external_reference_stats) {
i::ExternalReferenceTable::instance(isolate)->PrintCount();
}
#endif // DEBUG
i::SnapshotData startup_snapshot(&startup_serializer);
StartupData result =
i::Snapshot::CreateSnapshotBlob(&startup_snapshot, &context_snapshots);
......
......@@ -11,6 +11,11 @@
#include "src/deoptimizer.h"
#include "src/ic/stub-cache.h"
#if defined(DEBUG) && defined(V8_OS_LINUX) && !defined(V8_OS_ANDROID)
#define SYMBOLIZE_FUNCTION
#include <execinfo.h>
#endif // DEBUG && V8_OS_LINUX && !V8_OS_ANDROID
namespace v8 {
namespace internal {
......@@ -43,6 +48,28 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
AddApiReferences(isolate);
}
#ifdef DEBUG
void ExternalReferenceTable::ResetCount() {
for (ExternalReferenceEntry& entry : refs_) entry.count = 0;
}
void ExternalReferenceTable::PrintCount() {
for (int i = 0; i < refs_.length(); i++) {
v8::base::OS::Print("index=%5d count=%5d %-60s\n", i, refs_[i].count,
refs_[i].name);
}
}
#endif // DEBUG
// static
const char* ExternalReferenceTable::ResolveSymbol(void* address) {
#ifdef SYMBOLIZE_FUNCTION
return backtrace_symbols(&address, 1)[0];
#else
return "<unresolved>";
#endif // SYMBOLIZE_FUNCTION
}
void ExternalReferenceTable::AddReferences(Isolate* isolate) {
// Miscellaneous
Add(ExternalReference::roots_array_start(isolate).address(),
......@@ -336,22 +363,24 @@ void ExternalReferenceTable::AddAccessors(Isolate* isolate) {
};
static const AccessorRefTable getters[] = {
#define ACCESSOR_INFO_DECLARATION(name) \
{FUNCTION_ADDR(&Accessors::name##Getter), "Accessors::" #name "Getter"},
ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
#define ACCESSOR_INFO_DECLARATION(name) \
{ FUNCTION_ADDR(&Accessors::name##Getter), \
"Redirect to Accessors::" #name "Getter"},
ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
#undef ACCESSOR_INFO_DECLARATION
};
static const AccessorRefTable setters[] = {
#define ACCESSOR_SETTER_DECLARATION(name) \
{FUNCTION_ADDR(&Accessors::name), "Accessors::" #name},
ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
{ FUNCTION_ADDR(&Accessors::name), "Accessors::" #name},
ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
#undef ACCESSOR_INFO_DECLARATION
};
for (unsigned i = 0; i < arraysize(getters); ++i) {
Add(getters[i].address, getters[i].name);
const char* name = getters[i].name + 12; // Skip "Redirect to " prefix.
Add(getters[i].address, name);
Add(AccessorInfo::redirect(isolate, getters[i].address, ACCESSOR_GETTER),
"");
getters[i].name);
}
for (unsigned i = 0; i < arraysize(setters); ++i) {
......@@ -412,7 +441,8 @@ void ExternalReferenceTable::AddApiReferences(Isolate* isolate) {
intptr_t* api_external_references = isolate->api_external_references();
if (api_external_references != nullptr) {
while (*api_external_references != 0) {
Add(reinterpret_cast<Address>(*api_external_references), "<embedder>");
Address address = reinterpret_cast<Address>(*api_external_references);
Add(address, ResolveSymbol(address));
api_external_references++;
}
}
......
......@@ -23,12 +23,24 @@ class ExternalReferenceTable {
Address address(uint32_t i) { return refs_[i].address; }
const char* name(uint32_t i) { return refs_[i].name; }
#ifdef DEBUG
void increment_count(uint32_t i) { refs_[i].count++; }
int count(uint32_t i) { return refs_[i].count; }
void ResetCount();
void PrintCount();
#endif // DEBUG
static const char* ResolveSymbol(void* address);
static const int kDeoptTableSerializeEntryCount = 64;
private:
struct ExternalReferenceEntry {
Address address;
const char* name;
#ifdef DEBUG
int count;
#endif // DEBUG
};
explicit ExternalReferenceTable(Isolate* isolate);
......
......@@ -627,6 +627,10 @@ DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
DEFINE_BOOL(serialize_eager, false, "compile eagerly when caching scripts")
DEFINE_BOOL(serialize_age_code, false, "pre age code in the code cache")
DEFINE_BOOL(trace_serializer, false, "print code serializer trace")
#ifdef DEBUG
DEFINE_BOOL(external_reference_stats, false,
"print statistics on external references used during serialization")
#endif // DEBUG
// compiler.cc
DEFINE_INT(min_preparse_length, 1024,
......
......@@ -8,25 +8,21 @@
#include "src/ic/stub-cache.h"
#include "src/list-inl.h"
#if defined(DEBUG) && defined(V8_OS_LINUX) && !defined(V8_OS_ANDROID)
#define SYMBOLIZE_FUNCTION
#include <execinfo.h>
#endif // DEBUG && V8_OS_LINUX && !V8_OS_ANDROID
namespace v8 {
namespace internal {
ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
map_ = isolate->external_reference_map();
#ifdef DEBUG
table_ = ExternalReferenceTable::instance(isolate);
#endif // DEBUG
if (map_ != nullptr) return;
map_ = new AddressToIndexHashMap();
ExternalReferenceTable* table = ExternalReferenceTable::instance(isolate);
for (uint32_t i = 0; i < table->size(); ++i) {
Address addr = table->address(i);
// We expect no duplicate external references entries in the table.
// AccessorRefTable getter may have duplicates, indicated by an empty string
// as name.
DCHECK(table->name(i)[0] == '\0' || map_->Get(addr).IsNothing());
DCHECK(map_->Get(addr).IsNothing() ||
strncmp(table->name(i), "Redirect to ", 12) == 0);
map_->Set(addr, i);
DCHECK(map_->Get(addr).IsJust());
}
......@@ -36,13 +32,14 @@ ExternalReferenceEncoder::ExternalReferenceEncoder(Isolate* isolate) {
uint32_t ExternalReferenceEncoder::Encode(Address address) const {
Maybe<uint32_t> maybe_index = map_->Get(address);
if (maybe_index.IsNothing()) {
void* function_addr = address;
v8::base::OS::PrintError("Unknown external reference %p.\n", function_addr);
#ifdef SYMBOLIZE_FUNCTION
v8::base::OS::PrintError("%s\n", backtrace_symbols(&function_addr, 1)[0]);
#endif // SYMBOLIZE_FUNCTION
void* addr = address;
v8::base::OS::PrintError("Unknown external reference %p.\n", addr);
v8::base::OS::PrintError("%s", ExternalReferenceTable::ResolveSymbol(addr));
v8::base::OS::Abort();
}
#ifdef DEBUG
table_->increment_count(maybe_index.FromJust());
#endif // DEBUG
return maybe_index.FromJust();
}
......
......@@ -24,6 +24,9 @@ class ExternalReferenceEncoder {
private:
AddressToIndexHashMap* map_;
#ifdef DEBUG
ExternalReferenceTable* table_;
#endif // DEBUG
DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
};
......
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