Commit aa351c24 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[frames] Use stable addresses for the InnerPointerToCodeCache

The InnerPointerToCodeCache was masking out the Page address to get stable
hashes. However, for pointers into the embedded code this still introduces a
sources of randomness due to how the data is mapped in. This is fixed by
using offsets relative to the start of the embedded data.

Hopefully this will fix one category of flaky tests unde with
v8_enable_verify_predictable  enabled.

Change-Id: I6bc3a1b6a03555341a9e4387e8bc058921298ef1
Reviewed-on: https://chromium-review.googlesource.com/c/1327045Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57392}
parent 7698d8d6
......@@ -15,6 +15,7 @@
#include "src/objects/smi.h"
#include "src/register-configuration.h"
#include "src/safepoint-table.h"
#include "src/snapshot/snapshot.h"
#include "src/string-stream.h"
#include "src/visitors.h"
#include "src/vm-state-inl.h"
......@@ -2130,12 +2131,24 @@ void InternalFrame::Iterate(RootVisitor* v) const {
// -------------------------------------------------------------------------
namespace {
uint32_t PcAddressForHashing(Isolate* isolate, Address address) {
if (InstructionStream::PcIsOffHeap(isolate, address)) {
// Ensure that we get predictable hashes for addresses in embedded code.
return EmbeddedData::FromBlob(isolate).AddressForHashing(address);
}
return ObjectAddressForHashing(reinterpret_cast<void*>(address));
}
} // namespace
InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
isolate_->counters()->pc_to_code()->Increment();
DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
uint32_t hash = ComputeUnseededHash(
ObjectAddressForHashing(reinterpret_cast<void*>(inner_pointer)));
uint32_t hash =
ComputeUnseededHash(PcAddressForHashing(isolate_, inner_pointer));
uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
InnerPointerToCodeCacheEntry* entry = cache(index);
if (entry->inner_pointer == inner_pointer) {
......
......@@ -15,7 +15,7 @@ namespace internal {
bool InstructionStream::PcIsOffHeap(Isolate* isolate, Address pc) {
if (FLAG_embedded_builtins) {
const Address start = reinterpret_cast<Address>(isolate->embedded_blob());
return start <= pc && pc < start + isolate->embedded_blob_size();
return IsInRange(pc, start, start + isolate->embedded_blob_size());
} else {
return false;
}
......
......@@ -375,14 +375,6 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
return d;
}
EmbeddedData EmbeddedData::FromBlob() {
const uint8_t* data = Isolate::CurrentEmbeddedBlob();
uint32_t size = Isolate::CurrentEmbeddedBlobSize();
DCHECK_NOT_NULL(data);
DCHECK_LT(0, size);
return {data, size};
}
Address EmbeddedData::InstructionStartOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
const struct Metadata* metadata = Metadata();
......
......@@ -53,7 +53,16 @@ class SnapshotData : public SerializedData {
class EmbeddedData final {
public:
static EmbeddedData FromIsolate(Isolate* isolate);
static EmbeddedData FromBlob();
static EmbeddedData FromBlob() {
return EmbeddedData(Isolate::CurrentEmbeddedBlob(),
Isolate::CurrentEmbeddedBlobSize());
}
static EmbeddedData FromBlob(Isolate* isolate) {
return EmbeddedData(isolate->embedded_blob(),
isolate->embedded_blob_size());
}
const uint8_t* data() const { return data_; }
uint32_t size() const { return size_; }
......@@ -65,6 +74,12 @@ class EmbeddedData final {
bool ContainsBuiltin(int i) const { return InstructionSizeOfBuiltin(i) > 0; }
uint32_t AddressForHashing(Address addr) {
Address start = reinterpret_cast<Address>(data_);
DCHECK(IsInRange(addr, start, start + size_));
return static_cast<uint32_t>(addr - start);
}
// Padded with kCodeAlignment.
uint32_t PaddedInstructionSizeOfBuiltin(int i) const {
uint32_t size = InstructionSizeOfBuiltin(i);
......@@ -106,7 +121,11 @@ class EmbeddedData final {
}
private:
EmbeddedData(const uint8_t* data, uint32_t size) : data_(data), size_(size) {}
explicit EmbeddedData(const uint8_t* data, uint32_t size)
: data_(data), size_(size) {
DCHECK_NOT_NULL(data);
DCHECK_LT(0, size);
}
const Metadata* Metadata() const {
return reinterpret_cast<const struct Metadata*>(data_ + MetadataOffset());
......
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