Commit 3ca76de1 authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Use cage-friendly HeapObject::map() in compiler

This will allow making HeapObject::IsBlah() checks faster when external
code space is enabled.

Bug: v8:11880
Change-Id: I68473ba88063c555c90330c9748462adeb35aa0b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3308797Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78156}
parent 391f9c25
......@@ -365,20 +365,22 @@ base::Optional<ObjectRef> GetOwnFastDataPropertyFromHeap(
base::Optional<Object> constant;
{
DisallowGarbageCollection no_gc;
PtrComprCageBase cage_base = broker->cage_base();
// This check to ensure the live map is the same as the cached map to
// to protect us against reads outside the bounds of the heap. This could
// happen if the Ref was created in a prior GC epoch, and the object
// shrunk in size. It might end up at the edge of a heap boundary. If
// we see that the map is the same in this GC epoch, we are safe.
Map map = holder.object()->map(kAcquireLoad);
Map map = holder.object()->map(cage_base, kAcquireLoad);
if (*holder.map().object() != map) {
TRACE_BROKER_MISSING(broker, "Map changed for " << holder);
return {};
}
if (field_index.is_inobject()) {
constant = holder.object()->RawInobjectPropertyAt(map, field_index);
constant =
holder.object()->RawInobjectPropertyAt(cage_base, map, field_index);
if (!constant.has_value()) {
TRACE_BROKER_MISSING(
broker, "Constant field in " << holder << " is unsafe to read");
......@@ -386,12 +388,12 @@ base::Optional<ObjectRef> GetOwnFastDataPropertyFromHeap(
}
} else {
Object raw_properties_or_hash =
holder.object()->raw_properties_or_hash(kRelaxedLoad);
holder.object()->raw_properties_or_hash(cage_base, kRelaxedLoad);
// Ensure that the object is safe to inspect.
if (broker->ObjectMayBeUninitialized(raw_properties_or_hash)) {
return {};
}
if (!raw_properties_or_hash.IsPropertyArray()) {
if (!raw_properties_or_hash.IsPropertyArray(cage_base)) {
TRACE_BROKER_MISSING(
broker,
"Expected PropertyArray for backing store in " << holder << ".");
......@@ -931,8 +933,8 @@ bool JSFunctionRef::IsConsistentWithHeapState() const {
HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
Handle<HeapObject> object, ObjectDataKind kind)
: ObjectData(broker, storage, object, kind),
map_(broker->GetOrCreateData(object->map(kAcquireLoad),
kAssumeMemoryFence)) {
map_(broker->GetOrCreateData(
object->map(broker->cage_base(), kAcquireLoad), kAssumeMemoryFence)) {
CHECK_IMPLIES(broker->mode() == JSHeapBroker::kSerialized,
kind == kBackgroundSerializedHeapObject);
}
......@@ -1678,7 +1680,8 @@ base::Optional<ObjectRef> JSObjectRef::RawInobjectPropertyAt(
Handle<Object> value;
{
DisallowGarbageCollection no_gc;
Map current_map = object()->map(kAcquireLoad);
PtrComprCageBase cage_base = broker()->cage_base();
Map current_map = object()->map(cage_base, kAcquireLoad);
// If the map changed in some prior GC epoch, our {index} could be
// outside the valid bounds of the cached map.
......@@ -1688,7 +1691,7 @@ base::Optional<ObjectRef> JSObjectRef::RawInobjectPropertyAt(
}
base::Optional<Object> maybe_value =
object()->RawInobjectPropertyAt(current_map, index);
object()->RawInobjectPropertyAt(cage_base, current_map, index);
if (!maybe_value.has_value()) {
TRACE_BROKER_MISSING(broker(),
"Unable to safely read property in " << *this);
......@@ -2527,7 +2530,9 @@ base::Optional<ObjectRef> SourceTextModuleRef::import_meta() const {
}
base::Optional<MapRef> HeapObjectRef::map_direct_read() const {
return TryMakeRef(broker(), object()->map(kAcquireLoad), kAssumeMemoryFence);
PtrComprCageBase cage_base = broker()->cage_base();
return TryMakeRef(broker(), object()->map(cage_base, kAcquireLoad),
kAssumeMemoryFence);
}
namespace {
......@@ -2562,7 +2567,7 @@ OddballType GetOddballType(Isolate* isolate, Map map) {
HeapObjectType HeapObjectRef::GetHeapObjectType() const {
if (data_->should_access_heap()) {
Map map = Handle<HeapObject>::cast(object())->map();
Map map = Handle<HeapObject>::cast(object())->map(broker()->cage_base());
HeapObjectType::Flags flags(0);
if (map.is_undetectable()) flags |= HeapObjectType::kUndetectable;
if (map.is_callable()) flags |= HeapObjectType::kCallable;
......
......@@ -43,6 +43,9 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
bool tracing_enabled, bool is_concurrent_inlining,
CodeKind code_kind)
: isolate_(isolate),
#if V8_COMPRESS_POINTERS
cage_base_(isolate),
#endif // V8_COMPRESS_POINTERS
zone_(broker_zone),
refs_(zone()->New<RefsMap>(kMinimalRefsBucketCount, AddressMatcher(),
zone())),
......
......@@ -114,6 +114,17 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
void InitializeAndStartSerializing();
Isolate* isolate() const { return isolate_; }
// The pointer compression cage base value used for decompression of all
// tagged values except references to Code objects.
PtrComprCageBase cage_base() const {
#if V8_COMPRESS_POINTERS
return cage_base_;
#else
return PtrComprCageBase{};
#endif // V8_COMPRESS_POINTERS
}
Zone* zone() const { return zone_; }
bool tracing_enabled() const { return tracing_enabled_; }
bool is_concurrent_inlining() const { return is_concurrent_inlining_; }
......@@ -413,6 +424,9 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
std::unique_ptr<CanonicalHandlesMap> canonical_handles);
Isolate* const isolate_;
#if V8_COMPRESS_POINTERS
const PtrComprCageBase cage_base_;
#endif // V8_COMPRESS_POINTERS
Zone* const zone_;
base::Optional<NativeContextRef> target_native_context_;
RefsMap* refs_;
......
......@@ -121,8 +121,14 @@ Address AbstractCode::InstructionEnd() {
}
}
bool AbstractCode::contains(Address inner_pointer) {
return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
bool AbstractCode::contains(Isolate* isolate, Address inner_pointer) {
PtrComprCageBase cage_base(isolate);
if (IsCode(cage_base)) {
return GetCode().contains(isolate, inner_pointer);
} else {
return (address() <= inner_pointer) &&
(inner_pointer <= address() + Size(cage_base));
}
}
CodeKind AbstractCode::kind() {
......@@ -435,7 +441,8 @@ bool Code::contains(Isolate* isolate, Address inner_pointer) {
return true;
}
}
return (address() <= inner_pointer) && (inner_pointer < address() + Size());
return (address() <= inner_pointer) &&
(inner_pointer < address() + CodeSize());
}
// static
......
......@@ -748,7 +748,7 @@ class AbstractCode : public HeapObject {
inline int SizeIncludingMetadata();
// Returns true if pc is inside this object's instructions.
inline bool contains(Address pc);
inline bool contains(Isolate* isolate, Address pc);
// Returns the kind of the code.
inline CodeKind kind();
......
......@@ -341,9 +341,8 @@ Object JSObject::RawFastPropertyAt(PtrComprCageBase cage_base,
}
}
base::Optional<Object> JSObject::RawInobjectPropertyAt(Map original_map,
FieldIndex index) const {
PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
base::Optional<Object> JSObject::RawInobjectPropertyAt(
PtrComprCageBase cage_base, Map original_map, FieldIndex index) const {
CHECK(index.is_inobject());
// This method implements a "snapshot" protocol to protect against reading out
......@@ -373,7 +372,7 @@ base::Optional<Object> JSObject::RawInobjectPropertyAt(Map original_map,
// given by the map and it will be a valid Smi or object pointer.
Object maybe_tagged_object =
TaggedField<Object>::Acquire_Load(cage_base, *this, index.offset());
if (original_map != map(kAcquireLoad)) return {};
if (original_map != map(cage_base, kAcquireLoad)) return {};
return maybe_tagged_object;
}
......
......@@ -665,8 +665,8 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
// in which this method is meant to be used, and what guarantees it
// provides against invalid reads from another thread during object
// mutation.
inline base::Optional<Object> RawInobjectPropertyAt(Map original_map,
FieldIndex index) const;
inline base::Optional<Object> RawInobjectPropertyAt(
PtrComprCageBase cage_base, Map original_map, FieldIndex index) const;
inline void FastPropertyAtPut(FieldIndex index, Object value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
......
......@@ -49,7 +49,7 @@ namespace internal {
static bool IsAddressWithinFuncCode(JSFunction function, Isolate* isolate,
void* addr) {
i::AbstractCode code = function.abstract_code(isolate);
return code.contains(reinterpret_cast<Address>(addr));
return code.contains(isolate, reinterpret_cast<Address>(addr));
}
static bool IsAddressWithinFuncCode(v8::Local<v8::Context> context,
......
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