blob: 4f8839aa53b385691805f07c710ef72cee20d021 [file] [log] [blame]
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CODEGEN_EXTERNAL_REFERENCE_TABLE_H_
#define V8_CODEGEN_EXTERNAL_REFERENCE_TABLE_H_
#include "src/builtins/accessors.h"
#include "src/builtins/builtins.h"
#include "src/codegen/external-reference.h"
#include "src/logging/counters-definitions.h"
namespace v8 {
namespace internal {
class Isolate;
// ExternalReferenceTable is a helper class that defines the relationship
// between external references and their encodings. It is used to build
// hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
class ExternalReferenceTable {
public:
// For the nullptr ref, see the constructor.
static constexpr int kSpecialReferenceCount = 1;
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);
#undef COUNT_C_BUILTIN
static constexpr int kRuntimeReferenceCount =
Runtime::kNumFunctions -
Runtime::kNumInlineFunctions; // Don't count dupe kInline... functions.
static constexpr int kIsolateAddressReferenceCount = kIsolateAddressCount;
static constexpr int kAccessorReferenceCount =
Accessors::kAccessorInfoCount + Accessors::kAccessorSetterCount;
// The number of stub cache external references, see AddStubCache.
static constexpr int kStubCacheReferenceCount = 12;
static constexpr int kStatsCountersReferenceCount =
#define SC(...) +1
STATS_COUNTER_NATIVE_CODE_LIST(SC);
#undef SC
static constexpr int kSizeIsolateIndependent =
kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
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;
Address address(uint32_t i) const { return ref_addr_[i]; }
const char* name(uint32_t i) const { return ref_name_[i]; }
bool is_initialized() const { return is_initialized_ != 0; }
static const char* ResolveSymbol(void* address);
static constexpr uint32_t OffsetOfEntry(uint32_t i) {
// Used in CodeAssembler::LookupExternalReference.
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);
int index = offset / kEntrySize;
return name(index);
}
ExternalReferenceTable() = default;
ExternalReferenceTable(const ExternalReferenceTable&) = delete;
ExternalReferenceTable& operator=(const ExternalReferenceTable&) = delete;
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 CopyIsolateIndependentReferences(int* index);
void AddIsolateDependentReferences(Isolate* isolate, int* index);
void AddIsolateAddresses(Isolate* isolate, int* index);
void AddStubCache(Isolate* isolate, int* index);
Address GetStatsCounterAddress(StatsCounter* counter);
void AddNativeCodeStatsCounters(Isolate* isolate, int* index);
STATIC_ASSERT(sizeof(Address) == kEntrySize);
Address ref_addr_[kSize];
static const char* const ref_name_[kSize];
// Not bool to guarantee deterministic size.
uint32_t is_initialized_ = 0;
// Redirect disabled stats counters to this field. This is done to make sure
// we can have a snapshot that includes native counters even when the embedder
// isn't collecting them.
// This field is uint32_t since the MacroAssembler and CodeStubAssembler
// accesses this field as a uint32_t.
uint32_t dummy_stats_counter_ = 0;
};
STATIC_ASSERT(ExternalReferenceTable::kSizeInBytes ==
sizeof(ExternalReferenceTable));
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_EXTERNAL_REFERENCE_TABLE_H_