Commit a1ba0a85 authored by Stephen Kyle's avatar Stephen Kyle Committed by Commit Bot

[ptr-compr][ic] Compress references in StubCache

The stub cache doubles in size when switching to 64-bit. The references
stored in it are not currently compressed even with ptr-compr enabled.

This patch compresses those references so the table is the same size on
32- and 64-bit architectures, which is beneficial on benchmarks which
utilise the stub cache heavily.

Reducing the stub cache size has lead to an improvement of 0.7% in
runs/minute being observed on Speedometer on a Pixel device, and 0.4% on
a Pixel3 device.

Also add constructors to [Strong]TaggedValue to support compression.

Cq-Include-Trybots: luci.v8.try:v8_linux64_pointer_compression_rel_ng
Cq-Include-Trybots: luci.v8.try:v8_linux64_arm64_pointer_compression_rel_ng
Change-Id: I3b643d674356deaa129588189df7adfc91d15db4
Bug: v8:7703
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1635694
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62308}
parent e05256a8
......@@ -2386,26 +2386,24 @@ void AccessorAssembler::TryProbeStubCacheTable(
const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift;
entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier));
// Check that the key in the entry matches the name.
Node* key_base = ExternalConstant(
ExternalReference::Create(stub_cache->key_reference(table)));
Node* entry_key = Load(MachineType::Pointer(), key_base, entry_offset);
GotoIf(WordNotEqual(name, entry_key), if_miss);
// Get the map entry from the cache.
DCHECK_EQ(kSystemPointerSize * 2,
stub_cache->map_reference(table).address() -
stub_cache->key_reference(table).address());
Node* entry_map =
Load(MachineType::Pointer(), key_base,
IntPtrAdd(entry_offset, IntPtrConstant(kSystemPointerSize * 2)));
GotoIf(WordNotEqual(map, entry_map), if_miss);
DCHECK_EQ(kSystemPointerSize, stub_cache->value_reference(table).address() -
stub_cache->key_reference(table).address());
// Check that the key in the entry matches the name.
DCHECK_EQ(0, offsetof(StubCache::Entry, key));
Node* cached_key = Load(MachineType::TaggedPointer(), key_base, entry_offset);
GotoIf(WordNotEqual(name, cached_key), if_miss);
// Check that the map in the entry matches.
Node* cached_map = Load(
MachineType::TaggedPointer(), key_base,
IntPtrAdd(entry_offset, IntPtrConstant(offsetof(StubCache::Entry, map))));
GotoIf(WordNotEqual(map, cached_map), if_miss);
TNode<MaybeObject> handler = ReinterpretCast<MaybeObject>(
Load(MachineType::AnyTagged(), key_base,
IntPtrAdd(entry_offset, IntPtrConstant(kSystemPointerSize))));
IntPtrAdd(entry_offset,
IntPtrConstant(offsetof(StubCache::Entry, value)))));
// We found the handler.
*var_handler = handler;
......
......@@ -9,6 +9,7 @@
#include "src/heap/heap-inl.h" // For InYoungGeneration().
#include "src/ic/ic-inl.h"
#include "src/logging/counters.h"
#include "src/objects/tagged-value-inl.h"
namespace v8 {
namespace internal {
......@@ -85,25 +86,28 @@ void StubCache::Set(Name name, Map map, MaybeObject handler) {
// Compute the primary entry.
int primary_offset = PrimaryOffset(name, map);
Entry* primary = entry(primary_, primary_offset);
MaybeObject old_handler(primary->value);
MaybeObject old_handler(
TaggedValue::ToMaybeObject(isolate(), primary->value));
// If the primary entry has useful data in it, we retire it to the
// secondary cache before overwriting it.
if (old_handler != MaybeObject::FromObject(
isolate_->builtins()->builtin(Builtins::kIllegal)) &&
primary->map != kNullAddress) {
Map old_map = Map::cast(Object(primary->map));
int seed = PrimaryOffset(Name::cast(Object(primary->key)), old_map);
int secondary_offset =
SecondaryOffset(Name::cast(Object(primary->key)), seed);
isolate()->builtins()->builtin(Builtins::kIllegal)) &&
!primary->map.IsSmi()) {
Map old_map =
Map::cast(StrongTaggedValue::ToObject(isolate(), primary->map));
int seed = PrimaryOffset(
Name::cast(StrongTaggedValue::ToObject(isolate(), primary->key)),
old_map);
int secondary_offset = SecondaryOffset(
Name::cast(StrongTaggedValue::ToObject(isolate(), primary->key)), seed);
Entry* secondary = entry(secondary_, secondary_offset);
*secondary = *primary;
}
// Update primary cache.
primary->key = name.ptr();
primary->value = handler.ptr();
primary->map = map.ptr();
primary->key = StrongTaggedValue(name);
primary->value = TaggedValue(handler);
primary->map = StrongTaggedValue(map);
isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
}
......@@ -111,13 +115,13 @@ MaybeObject StubCache::Get(Name name, Map map) {
DCHECK(CommonStubCacheChecks(this, name, map, MaybeObject()));
int primary_offset = PrimaryOffset(name, map);
Entry* primary = entry(primary_, primary_offset);
if (primary->key == name.ptr() && primary->map == map.ptr()) {
return MaybeObject(primary->value);
if (primary->key == name && primary->map == map) {
return TaggedValue::ToMaybeObject(isolate(), primary->value);
}
int secondary_offset = SecondaryOffset(name, primary_offset);
Entry* secondary = entry(secondary_, secondary_offset);
if (secondary->key == name.ptr() && secondary->map == map.ptr()) {
return MaybeObject(secondary->value);
if (secondary->key == name && secondary->map == map) {
return TaggedValue::ToMaybeObject(isolate(), secondary->value);
}
return MaybeObject();
}
......@@ -127,14 +131,14 @@ void StubCache::Clear() {
isolate_->builtins()->builtin(Builtins::kIllegal));
Name empty_string = ReadOnlyRoots(isolate()).empty_string();
for (int i = 0; i < kPrimaryTableSize; i++) {
primary_[i].key = empty_string.ptr();
primary_[i].map = kNullAddress;
primary_[i].value = empty.ptr();
primary_[i].key = StrongTaggedValue(empty_string);
primary_[i].map = StrongTaggedValue(Smi::zero());
primary_[i].value = TaggedValue(empty);
}
for (int j = 0; j < kSecondaryTableSize; j++) {
secondary_[j].key = empty_string.ptr();
secondary_[j].map = kNullAddress;
secondary_[j].value = empty.ptr();
secondary_[j].key = StrongTaggedValue(empty_string);
secondary_[j].map = StrongTaggedValue(Smi::zero());
secondary_[j].value = TaggedValue(empty);
}
}
......
......@@ -6,6 +6,7 @@
#define V8_IC_STUB_CACHE_H_
#include "src/objects/name.h"
#include "src/objects/tagged-value.h"
namespace v8 {
namespace internal {
......@@ -31,15 +32,14 @@ class SCTableReference {
class V8_EXPORT_PRIVATE StubCache {
public:
struct Entry {
// The values here have plain Address types because they are read
// directly from generated code. As a nice side effect, this keeps
// #includes lightweight.
Address key;
// {key} is a tagged Name pointer, may be cleared by setting to empty
// string.
StrongTaggedValue key;
// {value} is a tagged heap object reference (weak or strong), equivalent
// to a MaybeObject's payload.
Address value;
// {map} is a tagged Map pointer, or nullptr.
Address map;
TaggedValue value;
// {map} is a tagged Map pointer, may be cleared by setting to Smi::zero().
StrongTaggedValue map;
};
void Initialize();
......
......@@ -17,6 +17,16 @@
namespace v8 {
namespace internal {
inline StrongTaggedValue::StrongTaggedValue(Object o)
:
#ifdef V8_COMPRESS_POINTERS
TaggedImpl(CompressTagged(o.ptr()))
#else
TaggedImpl(o.ptr())
#endif
{
}
Object StrongTaggedValue::ToObject(Isolate* isolate, StrongTaggedValue object) {
#ifdef V8_COMPRESS_POINTERS
return Object(DecompressTaggedAny(isolate, object.ptr()));
......@@ -25,6 +35,16 @@ Object StrongTaggedValue::ToObject(Isolate* isolate, StrongTaggedValue object) {
#endif
}
inline TaggedValue::TaggedValue(MaybeObject o)
:
#ifdef V8_COMPRESS_POINTERS
TaggedImpl(CompressTagged(o.ptr()))
#else
TaggedImpl(o.ptr())
#endif
{
}
MaybeObject TaggedValue::ToMaybeObject(Isolate* isolate, TaggedValue object) {
#ifdef V8_COMPRESS_POINTERS
return MaybeObject(DecompressTaggedAny(isolate, object.ptr()));
......
......@@ -21,6 +21,7 @@ class StrongTaggedValue
public:
constexpr StrongTaggedValue() : TaggedImpl() {}
explicit constexpr StrongTaggedValue(Tagged_t ptr) : TaggedImpl(ptr) {}
explicit StrongTaggedValue(Object o);
inline static Object ToObject(Isolate* isolate, StrongTaggedValue object);
};
......@@ -32,6 +33,7 @@ class TaggedValue : public TaggedImpl<HeapObjectReferenceType::WEAK, Tagged_t> {
public:
constexpr TaggedValue() : TaggedImpl() {}
explicit constexpr TaggedValue(Tagged_t ptr) : TaggedImpl(ptr) {}
explicit TaggedValue(MaybeObject o);
inline static MaybeObject ToMaybeObject(Isolate* isolate, TaggedValue object);
};
......
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