Commit 6c40a668 authored by Daan de Graaf's avatar Daan de Graaf Committed by Commit Bot

Resolve external refs without isolate.

Makes ExternalRefEncoder work even if no isolate is available,
by separating V8 builtin external references from isolate dependent ones,
and making the first set available without providing an isolate.

This is used when disassembling external references in wasm functions.

Bug: v8:11373
Change-Id: I9a177618185a6e5612182bcb02be7cc1978e8f34
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2799511Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Commit-Queue: Daan de Graaf <daagra@google.com>
Cr-Commit-Position: refs/heads/master@{#74025}
parent 3c922887
......@@ -33,20 +33,24 @@ namespace internal {
// clang-format off
const char* const
ExternalReferenceTable::ref_name_[ExternalReferenceTable::kSize] = {
// === Isolate independent ===
// Special references:
"nullptr",
// External references:
// External references (without isolate):
EXTERNAL_REFERENCE_LIST(ADD_EXT_REF_NAME)
EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXT_REF_NAME)
// Builtins:
BUILTIN_LIST_C(ADD_BUILTIN_NAME)
// Runtime functions:
FOR_EACH_INTRINSIC(ADD_RUNTIME_FUNCTION)
// Isolate addresses:
FOR_EACH_ISOLATE_ADDRESS_NAME(ADD_ISOLATE_ADDR)
// Accessors:
ACCESSOR_INFO_LIST_GENERATOR(ADD_ACCESSOR_INFO_NAME, /* not used */)
ACCESSOR_SETTER_LIST(ADD_ACCESSOR_SETTER_NAME)
// === Isolate dependent ===
// External references (with isolate):
EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXT_REF_NAME)
// Isolate addresses:
FOR_EACH_ISOLATE_ADDRESS_NAME(ADD_ISOLATE_ADDR)
// Stub cache:
"Load StubCache::primary_->key",
"Load StubCache::primary_->value",
......@@ -72,6 +76,11 @@ const char* const
#undef ADD_ACCESSOR_SETTER_NAME
#undef ADD_STATS_COUNTER_NAME
namespace {
static Address ref_addr_isolate_independent_
[ExternalReferenceTable::kSizeIsolateIndependent] = {0};
} // namespace
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
......@@ -81,13 +90,10 @@ BUILTIN_LIST_C(FORWARD_DECLARE)
void ExternalReferenceTable::Init(Isolate* isolate) {
int index = 0;
// kNullAddress is preserved through serialization/deserialization.
Add(kNullAddress, &index);
AddReferences(isolate, &index);
AddBuiltins(&index);
AddRuntimeFunctions(&index);
CopyIsolateIndependentReferences(&index);
AddIsolateDependentReferences(isolate, &index);
AddIsolateAddresses(isolate, &index);
AddAccessors(&index);
AddStubCache(isolate, &index);
AddNativeCodeStatsCounters(isolate, &index);
is_initialized_ = static_cast<uint32_t>(true);
......@@ -108,28 +114,66 @@ const char* ExternalReferenceTable::ResolveSymbol(void* address) {
#endif // SYMBOLIZE_FUNCTION
}
void ExternalReferenceTable::InitializeOncePerProcess() {
int index = 0;
// kNullAddress is preserved through serialization/deserialization.
AddIsolateIndependent(kNullAddress, &index);
AddIsolateIndependentReferences(&index);
AddBuiltins(&index);
AddRuntimeFunctions(&index);
AddAccessors(&index);
CHECK_EQ(kSizeIsolateIndependent, index);
}
const char* ExternalReferenceTable::NameOfIsolateIndependentAddress(
Address address) {
for (int i = 0; i < kSizeIsolateIndependent; i++) {
if (ref_addr_isolate_independent_[i] == address) {
return ref_name_[i];
}
}
return "<unknown>";
}
void ExternalReferenceTable::Add(Address address, int* index) {
ref_addr_[(*index)++] = address;
}
void ExternalReferenceTable::AddReferences(Isolate* isolate, int* index) {
void ExternalReferenceTable::AddIsolateIndependent(Address address,
int* index) {
ref_addr_isolate_independent_[(*index)++] = address;
}
void ExternalReferenceTable::AddIsolateIndependentReferences(int* index) {
CHECK_EQ(kSpecialReferenceCount, *index);
#define ADD_EXTERNAL_REFERENCE(name, desc) \
Add(ExternalReference::name().address(), index);
AddIsolateIndependent(ExternalReference::name().address(), index);
EXTERNAL_REFERENCE_LIST(ADD_EXTERNAL_REFERENCE)
#undef ADD_EXTERNAL_REFERENCE
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent,
*index);
}
void ExternalReferenceTable::AddIsolateDependentReferences(Isolate* isolate,
int* index) {
CHECK_EQ(kSizeIsolateIndependent, *index);
#define ADD_EXTERNAL_REFERENCE(name, desc) \
Add(ExternalReference::name(isolate).address(), index);
EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXTERNAL_REFERENCE)
#undef ADD_EXTERNAL_REFERENCE
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent,
*index);
}
void ExternalReferenceTable::AddBuiltins(int* index) {
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent,
*index);
static const Address c_builtins[] = {
#define DEF_ENTRY(Name, ...) FUNCTION_ADDR(&Builtin_##Name),
......@@ -137,16 +181,16 @@ void ExternalReferenceTable::AddBuiltins(int* index) {
#undef DEF_ENTRY
};
for (Address addr : c_builtins) {
Add(ExternalReference::Create(addr).address(), index);
AddIsolateIndependent(ExternalReference::Create(addr).address(), index);
}
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount,
*index);
}
void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount,
*index);
......@@ -157,33 +201,38 @@ void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
};
for (Runtime::FunctionId fId : runtime_functions) {
Add(ExternalReference::Create(fId).address(), index);
AddIsolateIndependent(ExternalReference::Create(fId).address(), index);
}
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount + kRuntimeReferenceCount,
*index);
}
void ExternalReferenceTable::CopyIsolateIndependentReferences(int* index) {
CHECK_EQ(0, *index);
std::copy(ref_addr_isolate_independent_,
ref_addr_isolate_independent_ + kSizeIsolateIndependent, ref_addr_);
*index += kSizeIsolateIndependent;
}
void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount,
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent,
*index);
for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
}
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount,
*index);
}
void ExternalReferenceTable::AddAccessors(int* index) {
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount,
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount + kRuntimeReferenceCount,
*index);
static const Address accessors[] = {
......@@ -199,19 +248,18 @@ void ExternalReferenceTable::AddAccessors(int* index) {
};
for (Address addr : accessors) {
Add(addr, index);
AddIsolateIndependent(addr, index);
}
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount,
kAccessorReferenceCount,
*index);
}
void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount,
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount,
*index);
StubCache* load_stub_cache = isolate->load_stub_cache();
......@@ -235,10 +283,8 @@ void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
index);
Add(store_stub_cache->map_reference(StubCache::kSecondary).address(), index);
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount +
kStubCacheReferenceCount,
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount + kStubCacheReferenceCount,
*index);
}
......@@ -251,10 +297,8 @@ Address ExternalReferenceTable::GetStatsCounterAddress(StatsCounter* counter) {
void ExternalReferenceTable::AddNativeCodeStatsCounters(Isolate* isolate,
int* index) {
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount +
kStubCacheReferenceCount,
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount + kStubCacheReferenceCount,
*index);
Counters* counters = isolate->counters();
......@@ -263,10 +307,9 @@ void ExternalReferenceTable::AddNativeCodeStatsCounters(Isolate* isolate,
STATS_COUNTER_NATIVE_CODE_LIST(SC)
#undef SC
CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount +
kStubCacheReferenceCount + kStatsCountersReferenceCount,
CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount + kStubCacheReferenceCount +
kStatsCountersReferenceCount,
*index);
CHECK_EQ(kSize, *index);
}
......
......@@ -24,8 +24,10 @@ class ExternalReferenceTable {
public:
// For the nullptr ref, see the constructor.
static constexpr int kSpecialReferenceCount = 1;
static constexpr int kExternalReferenceCount =
ExternalReference::kExternalReferenceCount;
static constexpr int kExternalReferenceCountIsolateIndependent =
ExternalReference::kExternalReferenceCountIsolateIndependent;
static constexpr int kExternalReferenceCountIsolateDependent =
ExternalReference::kExternalReferenceCountIsolateDependent;
static constexpr int kBuiltinsReferenceCount =
#define COUNT_C_BUILTIN(...) +1
BUILTIN_LIST_C(COUNT_C_BUILTIN);
......@@ -42,11 +44,14 @@ class ExternalReferenceTable {
#define SC(...) +1
STATS_COUNTER_NATIVE_CODE_LIST(SC);
#undef SC
static constexpr int kSize =
kSpecialReferenceCount + kExternalReferenceCount +
static constexpr int kSizeIsolateIndependent =
kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount +
kStubCacheReferenceCount + kStatsCountersReferenceCount;
kAccessorReferenceCount;
static constexpr int kSize =
kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount + kStubCacheReferenceCount +
kStatsCountersReferenceCount;
static constexpr uint32_t kEntrySize =
static_cast<uint32_t>(kSystemPointerSize);
static constexpr uint32_t kSizeInBytes = kSize * kEntrySize + 2 * kUInt32Size;
......@@ -63,6 +68,9 @@ class ExternalReferenceTable {
return i * kEntrySize;
}
static void InitializeOncePerProcess();
static const char* NameOfIsolateIndependentAddress(Address address);
const char* NameFromOffset(uint32_t offset) {
DCHECK_EQ(offset % kEntrySize, 0);
DCHECK_LT(offset, kSizeInBytes);
......@@ -76,13 +84,18 @@ class ExternalReferenceTable {
void Init(Isolate* isolate);
private:
static void AddIsolateIndependent(Address address, int* index);
static void AddIsolateIndependentReferences(int* index);
static void AddBuiltins(int* index);
static void AddRuntimeFunctions(int* index);
static void AddAccessors(int* index);
void Add(Address address, int* index);
void AddReferences(Isolate* isolate, int* index);
void AddBuiltins(int* index);
void AddRuntimeFunctions(int* index);
void CopyIsolateIndependentReferences(int* index);
void AddIsolateDependentReferences(Isolate* isolate, int* index);
void AddIsolateAddresses(Isolate* isolate, int* index);
void AddAccessors(int* index);
void AddStubCache(Isolate* isolate, int* index);
Address GetStatsCounterAddress(StatsCounter* counter);
......
......@@ -342,9 +342,10 @@ class ExternalReference {
PROFILING_GETTER_CALL
};
static constexpr int kExternalReferenceCount =
#define COUNT_EXTERNAL_REFERENCE(name, desc) +1
EXTERNAL_REFERENCE_LIST(COUNT_EXTERNAL_REFERENCE)
static constexpr int kExternalReferenceCountIsolateIndependent =
EXTERNAL_REFERENCE_LIST(COUNT_EXTERNAL_REFERENCE);
static constexpr int kExternalReferenceCountIsolateDependent =
EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(COUNT_EXTERNAL_REFERENCE);
#undef COUNT_EXTERNAL_REFERENCE
......
......@@ -237,10 +237,11 @@ static void PrintRelocInfo(StringBuilder* out, Isolate* isolate,
out->AddFormatted(" ;; %sobject: %s",
is_compressed ? "(compressed) " : "", obj_name.get());
} else if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
Address address = relocinfo->target_external_reference();
const char* reference_name =
ref_encoder ? ref_encoder->NameOfAddress(
isolate, relocinfo->target_external_reference())
: "unknown";
ref_encoder
? ref_encoder->NameOfAddress(isolate, address)
: ExternalReferenceTable::NameOfIsolateIndependentAddress(address);
out->AddFormatted(" ;; external reference (%s)", reference_name);
} else if (RelocInfo::IsCodeTargetMode(rmode)) {
out->AddFormatted(" ;; code:");
......@@ -441,14 +442,16 @@ int Disassembler::Decode(Isolate* isolate, std::ostream* os, byte* begin,
"Builtins disassembly requires a readable .text section");
V8NameConverter v8NameConverter(isolate, code);
if (isolate) {
// We have an isolate, so support external reference names.
// We have an isolate, so support external reference names from V8 and
// embedder.
SealHandleScope shs(isolate);
DisallowGarbageCollection no_alloc;
ExternalReferenceEncoder ref_encoder(isolate);
return DecodeIt(isolate, &ref_encoder, os, code, v8NameConverter, begin,
end, current_pc);
} else {
// No isolate => isolate-independent code. No external reference names.
// No isolate => isolate-independent code. Only V8 External references
// available.
return DecodeIt(nullptr, nullptr, os, code, v8NameConverter, begin, end,
current_pc);
}
......
......@@ -164,6 +164,8 @@ void V8::InitializeOncePerProcessImpl() {
#if V8_ENABLE_WEBASSEMBLY
wasm::WasmEngine::InitializeOncePerProcess();
#endif // V8_ENABLE_WEBASSEMBLY
ExternalReferenceTable::InitializeOncePerProcess();
}
void V8::InitializeOncePerProcess() {
......
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