blob: 5db9b0fcc1e6cba563e7d3d947db8e93c84817ce [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_EXTERNAL_REFERENCE_TABLE_H_
#define V8_EXTERNAL_REFERENCE_TABLE_H_
#include <vector>
#include "src/builtins/accessors.h"
#include "src/builtins/builtins.h"
#include "src/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 kExternalReferenceCount =
ExternalReference::kExternalReferenceCount;
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 kSize =
kSpecialReferenceCount + kExternalReferenceCount +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kIsolateAddressReferenceCount + kAccessorReferenceCount +
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;
}
const char* NameFromOffset(uint32_t offset) {
DCHECK_EQ(offset % kEntrySize, 0);
DCHECK_LT(offset, kSizeInBytes);
int index = offset / kEntrySize;
return name(index);
}
ExternalReferenceTable() = default;
void Init(Isolate* isolate);
private:
void Add(Address address, int* index);
void AddReferences(Isolate* isolate, int* index);
void AddBuiltins(int* index);
void AddRuntimeFunctions(int* index);
void AddIsolateAddresses(Isolate* isolate, int* index);
void AddAccessors(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;
DISALLOW_COPY_AND_ASSIGN(ExternalReferenceTable);
};
STATIC_ASSERT(ExternalReferenceTable::kSizeInBytes ==
sizeof(ExternalReferenceTable));
} // namespace internal
} // namespace v8
#endif // V8_EXTERNAL_REFERENCE_TABLE_H_