[ubsan] Port FeedbackVector and FeedbackMetadata
to the new design. Bug: v8:3770 Change-Id: I63291cc8eccfa1da20e84c6d3e9f48f253409396 Reviewed-on: https://chromium-review.googlesource.com/c/1355627 Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#57981}
This commit is contained in:
parent
9f6a854a7b
commit
f53d4d70a9
@ -601,7 +601,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
|
||||
DisallowHeapAllocation no_gc;
|
||||
if (osr_offset.IsNone()) {
|
||||
if (function->feedback_cell()->value()->IsFeedbackVector()) {
|
||||
FeedbackVector* feedback_vector = function->feedback_vector();
|
||||
FeedbackVector feedback_vector = function->feedback_vector();
|
||||
feedback_vector->EvictOptimizedCodeMarkedForDeoptimization(
|
||||
function->shared(), "GetCodeFromOptimizedCodeCache");
|
||||
Code code = feedback_vector->optimized_code();
|
||||
|
@ -499,7 +499,7 @@ std::unique_ptr<Coverage> Coverage::Collect(
|
||||
Handle<ArrayList> list = Handle<ArrayList>::cast(
|
||||
isolate->factory()->feedback_vectors_for_profiling_tools());
|
||||
for (int i = 0; i < list->Length(); i++) {
|
||||
FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
|
||||
FeedbackVector vector = FeedbackVector::cast(list->Get(i));
|
||||
SharedFunctionInfo shared = vector->shared_function_info();
|
||||
DCHECK(shared->IsSubjectToDebugging());
|
||||
uint32_t count = static_cast<uint32_t>(vector->invocation_count());
|
||||
@ -516,7 +516,7 @@ std::unique_ptr<Coverage> Coverage::Collect(
|
||||
HeapIterator heap_iterator(isolate->heap());
|
||||
while (HeapObject* current_obj = heap_iterator.next()) {
|
||||
if (!current_obj->IsFeedbackVector()) continue;
|
||||
FeedbackVector* vector = FeedbackVector::cast(current_obj);
|
||||
FeedbackVector vector = FeedbackVector::cast(current_obj);
|
||||
SharedFunctionInfo shared = vector->shared_function_info();
|
||||
if (!shared->IsSubjectToDebugging()) continue;
|
||||
uint32_t count = static_cast<uint32_t>(vector->invocation_count());
|
||||
@ -639,8 +639,7 @@ void Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) {
|
||||
shared->set_has_reported_binary_coverage(false);
|
||||
} else if (o->IsFeedbackVector()) {
|
||||
// In any case, clear any collected invocation counts.
|
||||
FeedbackVector* vector = FeedbackVector::cast(o);
|
||||
vector->clear_invocation_count();
|
||||
FeedbackVector::cast(o)->clear_invocation_count();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ std::unique_ptr<TypeProfile> TypeProfile::Collect(Isolate* isolate) {
|
||||
// TODO(franzih): Sort the vectors by script first instead of iterating
|
||||
// the list multiple times.
|
||||
for (int i = 0; i < list->Length(); i++) {
|
||||
FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
|
||||
FeedbackVector vector = FeedbackVector::cast(list->Get(i));
|
||||
SharedFunctionInfo info = vector->shared_function_info();
|
||||
DCHECK(info->IsSubjectToDebugging());
|
||||
|
||||
@ -86,7 +86,7 @@ void TypeProfile::SelectMode(Isolate* isolate, debug::TypeProfile::Mode mode) {
|
||||
isolate->factory()->feedback_vectors_for_profiling_tools());
|
||||
|
||||
for (int i = 0; i < list->Length(); i++) {
|
||||
FeedbackVector* vector = FeedbackVector::cast(list->Get(i));
|
||||
FeedbackVector vector = FeedbackVector::cast(list->Get(i));
|
||||
SharedFunctionInfo info = vector->shared_function_info();
|
||||
DCHECK(info->IsSubjectToDebugging());
|
||||
if (info->feedback_metadata()->HasTypeProfileSlot()) {
|
||||
|
@ -3422,10 +3422,10 @@ void TranslatedState::Init(Isolate* isolate, Address input_frame_pointer,
|
||||
void TranslatedState::Prepare(Address stack_frame_pointer) {
|
||||
for (auto& frame : frames_) frame.Handlify();
|
||||
|
||||
if (feedback_vector_ != nullptr) {
|
||||
if (!feedback_vector_.is_null()) {
|
||||
feedback_vector_handle_ =
|
||||
Handle<FeedbackVector>(feedback_vector_, isolate());
|
||||
feedback_vector_ = nullptr;
|
||||
feedback_vector_ = FeedbackVector();
|
||||
}
|
||||
stack_frame_pointer_ = stack_frame_pointer;
|
||||
|
||||
|
@ -397,7 +397,7 @@ class TranslatedState {
|
||||
};
|
||||
std::deque<ObjectPosition> object_positions_;
|
||||
Handle<FeedbackVector> feedback_vector_handle_;
|
||||
FeedbackVector* feedback_vector_ = nullptr;
|
||||
FeedbackVector feedback_vector_;
|
||||
FeedbackSlot feedback_slot_;
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,14 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
OBJECT_CONSTRUCTORS_IMPL(FeedbackVector, HeapObjectPtr)
|
||||
OBJECT_CONSTRUCTORS_IMPL(FeedbackMetadata, HeapObjectPtr)
|
||||
|
||||
NEVER_READ_ONLY_SPACE_IMPL(FeedbackVector)
|
||||
|
||||
CAST_ACCESSOR2(FeedbackVector)
|
||||
CAST_ACCESSOR2(FeedbackMetadata)
|
||||
|
||||
INT32_ACCESSORS(FeedbackMetadata, slot_count, kSlotCountOffset)
|
||||
|
||||
int32_t FeedbackMetadata::synchronized_slot_count() const {
|
||||
@ -27,12 +35,6 @@ int32_t FeedbackMetadata::synchronized_slot_count() const {
|
||||
FIELD_ADDR(this, kSlotCountOffset)));
|
||||
}
|
||||
|
||||
// static
|
||||
FeedbackMetadata* FeedbackMetadata::cast(Object* obj) {
|
||||
DCHECK(obj->IsFeedbackMetadata());
|
||||
return reinterpret_cast<FeedbackMetadata*>(obj);
|
||||
}
|
||||
|
||||
int32_t FeedbackMetadata::get(int index) const {
|
||||
DCHECK(index >= 0 && index < length());
|
||||
int offset = kHeaderSize + index * kInt32Size;
|
||||
@ -51,12 +53,6 @@ int FeedbackMetadata::length() const {
|
||||
return FeedbackMetadata::length(slot_count());
|
||||
}
|
||||
|
||||
// static
|
||||
FeedbackVector* FeedbackVector::cast(Object* obj) {
|
||||
DCHECK(obj->IsFeedbackVector());
|
||||
return reinterpret_cast<FeedbackVector*>(obj);
|
||||
}
|
||||
|
||||
int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
switch (kind) {
|
||||
case FeedbackSlotKind::kForIn:
|
||||
@ -103,7 +99,7 @@ INT32_ACCESSORS(FeedbackVector, deopt_count, kDeoptCountOffset)
|
||||
|
||||
bool FeedbackVector::is_empty() const { return length() == 0; }
|
||||
|
||||
FeedbackMetadata* FeedbackVector::metadata() const {
|
||||
FeedbackMetadata FeedbackVector::metadata() const {
|
||||
return shared_function_info()->feedback_metadata();
|
||||
}
|
||||
|
||||
@ -180,7 +176,7 @@ void FeedbackVector::set(int index, Object* value, WriteBarrierMode mode) {
|
||||
}
|
||||
|
||||
inline MaybeObjectSlot FeedbackVector::slots_start() {
|
||||
return HeapObject::RawMaybeWeakField(this, kFeedbackSlotsOffset);
|
||||
return RawMaybeWeakField(kFeedbackSlotsOffset);
|
||||
}
|
||||
|
||||
// Helper function to transform the feedback to BinaryOperationHint.
|
||||
|
@ -364,7 +364,7 @@ bool FeedbackVector::ClearSlots(Isolate* isolate) {
|
||||
|
||||
MaybeObject obj = Get(slot);
|
||||
if (obj != uninitialized_sentinel) {
|
||||
FeedbackNexus nexus(this, slot);
|
||||
FeedbackNexus nexus(*this, slot);
|
||||
feedback_updated |= nexus.Clear();
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,12 @@
|
||||
#include "src/globals.h"
|
||||
#include "src/objects/map.h"
|
||||
#include "src/objects/name.h"
|
||||
#include "src/objects/object-macros.h"
|
||||
#include "src/type-hints.h"
|
||||
#include "src/zone/zone-containers.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards):
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -145,17 +147,18 @@ class FeedbackMetadata;
|
||||
// - optimized code cell (weak cell or Smi marker)
|
||||
// followed by an array of feedback slots, of length determined by the feedback
|
||||
// metadata.
|
||||
class FeedbackVector : public HeapObject, public NeverReadOnlySpaceObject {
|
||||
class FeedbackVector : public HeapObjectPtr {
|
||||
public:
|
||||
// Casting.
|
||||
static inline FeedbackVector* cast(Object* obj);
|
||||
NEVER_READ_ONLY_SPACE
|
||||
|
||||
DECL_CAST2(FeedbackVector)
|
||||
|
||||
inline void ComputeCounts(int* with_type_info, int* generic,
|
||||
int* vector_ic_count);
|
||||
|
||||
inline bool is_empty() const;
|
||||
|
||||
inline FeedbackMetadata* metadata() const;
|
||||
inline FeedbackMetadata metadata() const;
|
||||
|
||||
// [shared_function_info]: The shared function info for the function with this
|
||||
// feedback vector.
|
||||
@ -303,7 +306,7 @@ class FeedbackVector : public HeapObject, public NeverReadOnlySpaceObject {
|
||||
static void AddToVectorsForProfilingTools(Isolate* isolate,
|
||||
Handle<FeedbackVector> vector);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackVector);
|
||||
OBJECT_CONSTRUCTORS(FeedbackVector, HeapObjectPtr);
|
||||
};
|
||||
|
||||
class V8_EXPORT_PRIVATE FeedbackVectorSpec {
|
||||
@ -448,10 +451,9 @@ class SharedFeedbackSlot {
|
||||
// of int32 data. The length is never stored - it is always calculated from
|
||||
// slot_count. All instances are created through the static New function, and
|
||||
// the number of slots is static once an instance is created.
|
||||
class FeedbackMetadata : public HeapObject {
|
||||
class FeedbackMetadata : public HeapObjectPtr {
|
||||
public:
|
||||
// Casting.
|
||||
static inline FeedbackMetadata* cast(Object* obj);
|
||||
DECL_CAST2(FeedbackMetadata)
|
||||
|
||||
// The number of slots that this metadata contains. Stored as an int32.
|
||||
DECL_INT32_ACCESSORS(slot_count)
|
||||
@ -515,7 +517,7 @@ class FeedbackMetadata : public HeapObject {
|
||||
kInt32Size * kBitsPerByte, uint32_t>
|
||||
VectorICComputer;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackMetadata);
|
||||
OBJECT_CONSTRUCTORS(FeedbackMetadata, HeapObjectPtr);
|
||||
};
|
||||
|
||||
// Verify that an empty hash field looks like a tagged object, but can't
|
||||
@ -532,7 +534,7 @@ class FeedbackMetadataIterator {
|
||||
next_slot_(FeedbackSlot(0)),
|
||||
slot_kind_(FeedbackSlotKind::kInvalid) {}
|
||||
|
||||
explicit FeedbackMetadataIterator(FeedbackMetadata* metadata)
|
||||
explicit FeedbackMetadataIterator(FeedbackMetadata metadata)
|
||||
: metadata_(metadata),
|
||||
next_slot_(FeedbackSlot(0)),
|
||||
slot_kind_(FeedbackSlotKind::kInvalid) {}
|
||||
@ -552,7 +554,7 @@ class FeedbackMetadataIterator {
|
||||
inline int entry_size() const;
|
||||
|
||||
private:
|
||||
FeedbackMetadata* metadata() const {
|
||||
FeedbackMetadata metadata() const {
|
||||
return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
|
||||
}
|
||||
|
||||
@ -560,7 +562,7 @@ class FeedbackMetadataIterator {
|
||||
// to have a single iterator implementation for both "handlified" and raw
|
||||
// pointer use cases.
|
||||
Handle<FeedbackMetadata> metadata_handle_;
|
||||
FeedbackMetadata* metadata_;
|
||||
FeedbackMetadata metadata_;
|
||||
FeedbackSlot cur_slot_;
|
||||
FeedbackSlot next_slot_;
|
||||
FeedbackSlotKind slot_kind_;
|
||||
@ -571,17 +573,16 @@ class FeedbackNexus final {
|
||||
public:
|
||||
FeedbackNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
|
||||
: vector_handle_(vector),
|
||||
vector_(nullptr),
|
||||
slot_(slot),
|
||||
kind_(vector->GetKind(slot)) {}
|
||||
FeedbackNexus(FeedbackVector* vector, FeedbackSlot slot)
|
||||
FeedbackNexus(FeedbackVector vector, FeedbackSlot slot)
|
||||
: vector_(vector), slot_(slot), kind_(vector->GetKind(slot)) {}
|
||||
|
||||
Handle<FeedbackVector> vector_handle() const {
|
||||
DCHECK_NULL(vector_);
|
||||
DCHECK(vector_.is_null());
|
||||
return vector_handle_;
|
||||
}
|
||||
FeedbackVector* vector() const {
|
||||
FeedbackVector vector() const {
|
||||
return vector_handle_.is_null() ? vector_ : *vector_handle_;
|
||||
}
|
||||
FeedbackSlot slot() const { return slot_; }
|
||||
@ -714,7 +715,7 @@ class FeedbackNexus final {
|
||||
// you have a handle to the vector that is better because more operations can
|
||||
// be done, like allocation.
|
||||
Handle<FeedbackVector> vector_handle_;
|
||||
FeedbackVector* vector_;
|
||||
FeedbackVector vector_;
|
||||
FeedbackSlot slot_;
|
||||
FeedbackSlotKind kind_;
|
||||
};
|
||||
@ -726,4 +727,6 @@ inline ForInHint ForInHintFromFeedback(int type_feedback);
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
#endif // V8_FEEDBACK_VECTOR_H_
|
||||
|
@ -153,6 +153,7 @@ class Handle final : public HandleBase {
|
||||
(std::is_same<S, ByteArray>::value || std::is_same<S, Code>::value ||
|
||||
std::is_same<S, Context>::value ||
|
||||
std::is_same<S, DescriptorArray>::value ||
|
||||
std::is_same<S, FeedbackVector>::value ||
|
||||
std::is_same<S, FixedArray>::value ||
|
||||
std::is_same<S, FixedArrayBase>::value ||
|
||||
std::is_same<S, FixedDoubleArray>::value ||
|
||||
|
@ -3634,8 +3634,9 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
// from a FunctionLiteral. Those can just reset this field to keep the
|
||||
// SharedFunctionInfo in a consistent state.
|
||||
if (maybe_builtin_index == Builtins::kCompileLazy) {
|
||||
share->set_raw_outer_scope_info_or_feedback_metadata(*the_hole_value(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
// TODO(3770): Drop explicit cast when migrating Oddball*.
|
||||
share->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
HeapObjectPtr::cast(*the_hole_value()), SKIP_WRITE_BARRIER);
|
||||
} else {
|
||||
share->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
*empty_feedback_metadata(), SKIP_WRITE_BARRIER);
|
||||
|
@ -378,7 +378,7 @@ class ObjectStatsCollectorImpl {
|
||||
void RecordVirtualBytecodeArrayDetails(BytecodeArray bytecode);
|
||||
void RecordVirtualCodeDetails(Code code);
|
||||
void RecordVirtualContext(Context context);
|
||||
void RecordVirtualFeedbackVectorDetails(FeedbackVector* vector);
|
||||
void RecordVirtualFeedbackVectorDetails(FeedbackVector vector);
|
||||
void RecordVirtualFixedArrayDetails(FixedArray array);
|
||||
void RecordVirtualFunctionTemplateInfoDetails(FunctionTemplateInfo* fti);
|
||||
void RecordVirtualJSGlobalObjectDetails(JSGlobalObject* object);
|
||||
@ -595,7 +595,7 @@ static ObjectStats::VirtualInstanceType GetFeedbackSlotType(
|
||||
}
|
||||
|
||||
void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
|
||||
FeedbackVector* vector) {
|
||||
FeedbackVector vector) {
|
||||
if (virtual_objects_.find(vector) == virtual_objects_.end()) {
|
||||
// Manually insert the feedback vector into the virtual object list, since
|
||||
// we're logging its component parts separately.
|
||||
|
@ -47,7 +47,7 @@ class WasmInstanceObject;
|
||||
V(EmbedderDataArray, EmbedderDataArray) \
|
||||
V(EphemeronHashTable, EphemeronHashTable) \
|
||||
V(FeedbackCell, FeedbackCell*) \
|
||||
V(FeedbackVector, FeedbackVector*) \
|
||||
V(FeedbackVector, FeedbackVector) \
|
||||
V(FixedArray, FixedArray) \
|
||||
V(FixedDoubleArray, FixedDoubleArray) \
|
||||
V(FixedFloat64Array, FixedFloat64Array) \
|
||||
|
@ -311,13 +311,13 @@ MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) {
|
||||
// static
|
||||
void IC::OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus,
|
||||
JSFunction* host_function, const char* reason) {
|
||||
FeedbackVector* vector = nexus->vector();
|
||||
FeedbackVector vector = nexus->vector();
|
||||
FeedbackSlot slot = nexus->slot();
|
||||
OnFeedbackChanged(isolate, vector, slot, host_function, reason);
|
||||
}
|
||||
|
||||
// static
|
||||
void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector,
|
||||
void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector vector,
|
||||
FeedbackSlot slot, JSFunction* host_function,
|
||||
const char* reason) {
|
||||
if (FLAG_trace_opt_verbose) {
|
||||
|
@ -62,7 +62,7 @@ class IC {
|
||||
static inline bool IsHandler(MaybeObject object);
|
||||
|
||||
// Nofity the IC system that a feedback has changed.
|
||||
static void OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector,
|
||||
static void OnFeedbackChanged(Isolate* isolate, FeedbackVector vector,
|
||||
FeedbackSlot slot, JSFunction* host_function,
|
||||
const char* reason);
|
||||
|
||||
|
@ -3566,7 +3566,7 @@ void Isolate::MaybeInitializeVectorListFromHeap() {
|
||||
while (HeapObject* current_obj = heap_iterator.next()) {
|
||||
if (!current_obj->IsFeedbackVector()) continue;
|
||||
|
||||
FeedbackVector* vector = FeedbackVector::cast(current_obj);
|
||||
FeedbackVector vector = FeedbackVector::cast(current_obj);
|
||||
SharedFunctionInfo shared = vector->shared_function_info();
|
||||
|
||||
// No need to preserve the feedback vector for non-user-visible functions.
|
||||
|
@ -767,9 +767,9 @@ void NativeContext::NativeContextVerify(Isolate* isolate) {
|
||||
|
||||
void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) {
|
||||
if (slot_count() == 0) {
|
||||
CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), this);
|
||||
CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), *this);
|
||||
} else {
|
||||
FeedbackMetadataIterator iter(this);
|
||||
FeedbackMetadataIterator iter(*this);
|
||||
while (iter.HasNext()) {
|
||||
iter.Next();
|
||||
FeedbackSlotKind kind = iter.kind();
|
||||
|
@ -1564,8 +1564,7 @@ int HeapObject::SizeFromMap(Map map) const {
|
||||
}
|
||||
if (instance_type == FEEDBACK_METADATA_TYPE) {
|
||||
return FeedbackMetadata::SizeFor(
|
||||
reinterpret_cast<const FeedbackMetadata*>(this)
|
||||
->synchronized_slot_count());
|
||||
FeedbackMetadata::unchecked_cast(this)->synchronized_slot_count());
|
||||
}
|
||||
if (instance_type == DESCRIPTOR_ARRAY_TYPE) {
|
||||
return DescriptorArray::SizeFor(
|
||||
@ -1603,7 +1602,7 @@ int HeapObject::SizeFromMap(Map map) const {
|
||||
}
|
||||
if (instance_type == FEEDBACK_VECTOR_TYPE) {
|
||||
return FeedbackVector::SizeFor(
|
||||
reinterpret_cast<const FeedbackVector*>(this)->length());
|
||||
FeedbackVector::unchecked_cast(this)->length());
|
||||
}
|
||||
if (instance_type == BIGINT_TYPE) {
|
||||
return BigInt::SizeFor(BigInt::unchecked_cast(this)->length());
|
||||
|
@ -1054,10 +1054,10 @@ void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) { // NOLINT
|
||||
}
|
||||
|
||||
void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
|
||||
HeapObject::PrintHeader(os, "FeedbackMetadata");
|
||||
PrintHeader(os, "FeedbackMetadata");
|
||||
os << "\n - slot_count: " << slot_count();
|
||||
|
||||
FeedbackMetadataIterator iter(this);
|
||||
FeedbackMetadataIterator iter(*this);
|
||||
while (iter.HasNext()) {
|
||||
FeedbackSlot slot = iter.Next();
|
||||
FeedbackSlotKind kind = iter.kind();
|
||||
@ -1067,7 +1067,7 @@ void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
|
||||
}
|
||||
|
||||
void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
|
||||
HeapObject::PrintHeader(os, "FeedbackVector");
|
||||
PrintHeader(os, "FeedbackVector");
|
||||
os << "\n - length: " << length();
|
||||
if (length() == 0) {
|
||||
os << " (empty)\n";
|
||||
@ -1105,7 +1105,7 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
|
||||
|
||||
void FeedbackVector::FeedbackSlotPrint(std::ostream& os,
|
||||
FeedbackSlot slot) { // NOLINT
|
||||
FeedbackNexus nexus(this, slot);
|
||||
FeedbackNexus nexus(*this, slot);
|
||||
nexus.Print(os);
|
||||
}
|
||||
|
||||
|
@ -14685,7 +14685,7 @@ int AbstractCode::SourceStatementPosition(int offset) {
|
||||
|
||||
void JSFunction::ClearTypeFeedbackInfo() {
|
||||
if (feedback_cell()->value()->IsFeedbackVector()) {
|
||||
FeedbackVector* vector = feedback_vector();
|
||||
FeedbackVector vector = feedback_vector();
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (vector->ClearSlots(isolate)) {
|
||||
IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(), this,
|
||||
|
@ -110,6 +110,8 @@ HeapObjectPtr::HeapObjectPtr(Address ptr, AllowInlineSmiStorage allow_smi)
|
||||
IsHeapObject());
|
||||
}
|
||||
|
||||
CAST_ACCESSOR2(HeapObjectPtr)
|
||||
|
||||
#define TYPE_CHECK_FORWARDER(Type) \
|
||||
bool HeapObjectPtr::Is##Type() const { \
|
||||
return reinterpret_cast<HeapObject*>(ptr())->Is##Type(); \
|
||||
|
@ -211,6 +211,8 @@ class HeapObjectPtr : public ObjectPtr {
|
||||
|
||||
inline Address GetFieldAddress(int field_offset) const;
|
||||
|
||||
DECL_CAST2(HeapObjectPtr)
|
||||
|
||||
protected:
|
||||
// Special-purpose constructor for subclasses that have fast paths where
|
||||
// their ptr() is a Smi.
|
||||
|
@ -429,7 +429,7 @@ ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
|
||||
|
||||
ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
|
||||
|
||||
FeedbackVector* JSFunction::feedback_vector() const {
|
||||
FeedbackVector JSFunction::feedback_vector() const {
|
||||
DCHECK(has_feedback_vector());
|
||||
return FeedbackVector::cast(feedback_cell()->value());
|
||||
}
|
||||
|
@ -990,7 +990,7 @@ class JSFunction : public JSObject {
|
||||
DECL_ACCESSORS(feedback_cell, FeedbackCell)
|
||||
|
||||
// feedback_vector() can be used once the function is compiled.
|
||||
inline FeedbackVector* feedback_vector() const;
|
||||
inline FeedbackVector feedback_vector() const;
|
||||
inline bool has_feedback_vector() const;
|
||||
static void EnsureFeedbackVector(Handle<JSFunction> function);
|
||||
|
||||
|
@ -311,10 +311,10 @@ void SharedFunctionInfo::set_scope_info(ScopeInfo scope_info,
|
||||
CONDITIONAL_WRITE_BARRIER(this, kNameOrScopeInfoOffset, scope_info, mode);
|
||||
}
|
||||
|
||||
ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
|
||||
HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
|
||||
ACCESSORS2(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
|
||||
HeapObjectPtr, kOuterScopeInfoOrFeedbackMetadataOffset)
|
||||
|
||||
HeapObject* SharedFunctionInfo::outer_scope_info() const {
|
||||
HeapObjectPtr SharedFunctionInfo::outer_scope_info() const {
|
||||
DCHECK(!is_compiled());
|
||||
DCHECK(!HasFeedbackMetadata());
|
||||
return raw_outer_scope_info_or_feedback_metadata();
|
||||
@ -338,28 +338,28 @@ ScopeInfo SharedFunctionInfo::GetOuterScopeInfo() const {
|
||||
return scope_info()->OuterScopeInfo();
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_outer_scope_info(HeapObject* value,
|
||||
void SharedFunctionInfo::set_outer_scope_info(HeapObjectPtr value,
|
||||
WriteBarrierMode mode) {
|
||||
DCHECK(!is_compiled());
|
||||
DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole());
|
||||
DCHECK(value->IsScopeInfo() || value->IsTheHole());
|
||||
return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
|
||||
set_raw_outer_scope_info_or_feedback_metadata(value, mode);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasFeedbackMetadata() const {
|
||||
return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
|
||||
}
|
||||
|
||||
FeedbackMetadata* SharedFunctionInfo::feedback_metadata() const {
|
||||
FeedbackMetadata SharedFunctionInfo::feedback_metadata() const {
|
||||
DCHECK(HasFeedbackMetadata());
|
||||
return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata* value,
|
||||
void SharedFunctionInfo::set_feedback_metadata(FeedbackMetadata value,
|
||||
WriteBarrierMode mode) {
|
||||
DCHECK(!HasFeedbackMetadata());
|
||||
DCHECK(value->IsFeedbackMetadata());
|
||||
return set_raw_outer_scope_info_or_feedback_metadata(value, mode);
|
||||
set_raw_outer_scope_info_or_feedback_metadata(value, mode);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::is_compiled() const {
|
||||
@ -653,11 +653,13 @@ void SharedFunctionInfo::DiscardCompiled(
|
||||
if (shared_info->is_compiled()) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
|
||||
HeapObject* outer_scope_info;
|
||||
HeapObjectPtr outer_scope_info;
|
||||
if (shared_info->scope_info()->HasOuterScopeInfo()) {
|
||||
outer_scope_info = shared_info->scope_info()->OuterScopeInfo();
|
||||
} else {
|
||||
outer_scope_info = ReadOnlyRoots(isolate).the_hole_value();
|
||||
// TODO(3770): Drop explicit cast when migrating Oddball*.
|
||||
outer_scope_info =
|
||||
HeapObjectPtr::cast(ReadOnlyRoots(isolate).the_hole_value());
|
||||
}
|
||||
// Raw setter to avoid validity checks, since we're performing the unusual
|
||||
// task of decompiling.
|
||||
|
@ -235,7 +235,7 @@ class SharedFunctionInfo : public HeapObjectPtr {
|
||||
|
||||
// [outer scope info | feedback metadata] Shared storage for outer scope info
|
||||
// (on uncompiled functions) and feedback metadata (on compiled functions).
|
||||
DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata, HeapObject)
|
||||
DECL_ACCESSORS2(raw_outer_scope_info_or_feedback_metadata, HeapObjectPtr)
|
||||
|
||||
// Get the outer scope info whether this function is compiled or not.
|
||||
inline bool HasOuterScopeInfo() const;
|
||||
@ -244,7 +244,7 @@ class SharedFunctionInfo : public HeapObjectPtr {
|
||||
// [feedback metadata] Metadata template for feedback vectors of instances of
|
||||
// this function.
|
||||
inline bool HasFeedbackMetadata() const;
|
||||
DECL_ACCESSORS(feedback_metadata, FeedbackMetadata)
|
||||
DECL_ACCESSORS2(feedback_metadata, FeedbackMetadata)
|
||||
|
||||
// Returns if this function has been compiled to native code yet.
|
||||
inline bool is_compiled() const;
|
||||
@ -664,7 +664,7 @@ class SharedFunctionInfo : public HeapObjectPtr {
|
||||
|
||||
// [outer scope info] The outer scope info, needed to lazily parse this
|
||||
// function.
|
||||
DECL_ACCESSORS(outer_scope_info, HeapObject)
|
||||
DECL_ACCESSORS2(outer_scope_info, HeapObjectPtr)
|
||||
|
||||
inline void set_kind(FunctionKind kind);
|
||||
|
||||
|
@ -1233,7 +1233,7 @@ void V8HeapExplorer::ExtractFixedArrayReferences(HeapEntry* entry,
|
||||
}
|
||||
|
||||
void V8HeapExplorer::ExtractFeedbackVectorReferences(
|
||||
HeapEntry* entry, FeedbackVector* feedback_vector) {
|
||||
HeapEntry* entry, FeedbackVector feedback_vector) {
|
||||
MaybeObject code = feedback_vector->optimized_code_weak_or_smi();
|
||||
HeapObject* code_heap_object;
|
||||
if (code->GetHeapObjectIfWeak(&code_heap_object)) {
|
||||
|
@ -377,7 +377,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
|
||||
JSGeneratorObject* generator);
|
||||
void ExtractFixedArrayReferences(HeapEntry* entry, FixedArray array);
|
||||
void ExtractFeedbackVectorReferences(HeapEntry* entry,
|
||||
FeedbackVector* feedback_vector);
|
||||
FeedbackVector feedback_vector);
|
||||
void ExtractDescriptorArrayReferences(HeapEntry* entry,
|
||||
DescriptorArray array);
|
||||
template <typename T>
|
||||
|
@ -202,7 +202,7 @@ class RootVisitor;
|
||||
EmptySlowElementDictionary) \
|
||||
V(FixedArray, empty_ordered_hash_map, EmptyOrderedHashMap) \
|
||||
V(FixedArray, empty_ordered_hash_set, EmptyOrderedHashSet) \
|
||||
V(FeedbackMetadata*, empty_feedback_metadata, EmptyFeedbackMetadata) \
|
||||
V(FeedbackMetadata, empty_feedback_metadata, EmptyFeedbackMetadata) \
|
||||
V(PropertyCell*, empty_property_cell, EmptyPropertyCell) \
|
||||
V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \
|
||||
V(InterceptorInfo*, noop_interceptor_info, NoOpInterceptorInfo) \
|
||||
|
@ -73,8 +73,7 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
|
||||
static void GetICCounts(JSFunction* function, int* ic_with_type_info_count,
|
||||
int* ic_generic_count, int* ic_total_count,
|
||||
int* type_info_percentage, int* generic_percentage) {
|
||||
// Harvest vector-ics.
|
||||
FeedbackVector* vector = function->feedback_vector();
|
||||
FeedbackVector vector = function->feedback_vector();
|
||||
vector->ComputeCounts(ic_with_type_info_count, ic_generic_count,
|
||||
ic_total_count);
|
||||
|
||||
|
@ -4393,7 +4393,7 @@ Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
|
||||
|
||||
void CheckIC(Handle<JSFunction> function, int slot_index,
|
||||
InlineCacheState state) {
|
||||
FeedbackVector* vector = function->feedback_vector();
|
||||
FeedbackVector vector = function->feedback_vector();
|
||||
FeedbackSlot slot(slot_index);
|
||||
FeedbackNexus nexus(vector, slot);
|
||||
CHECK_EQ(nexus.StateFromFeedback(), state);
|
||||
|
@ -193,7 +193,7 @@ TEST(ObjectMovesBeforeClearingWeakField) {
|
||||
Handle<FeedbackVector> fv =
|
||||
CreateFeedbackVectorForTest(CcTest::isolate(), factory);
|
||||
CHECK(Heap::InNewSpace(*fv));
|
||||
FeedbackVector* fv_location = *fv;
|
||||
FeedbackVector fv_location = *fv;
|
||||
{
|
||||
HandleScope inner_scope(isolate);
|
||||
// Create a new FixedArray which the FeedbackVector will point to.
|
||||
@ -210,7 +210,7 @@ TEST(ObjectMovesBeforeClearingWeakField) {
|
||||
|
||||
// Scavenger will move *fv.
|
||||
CcTest::CollectGarbage(NEW_SPACE);
|
||||
FeedbackVector* new_fv_location = *fv;
|
||||
FeedbackVector new_fv_location = *fv;
|
||||
CHECK_NE(fv_location, new_fv_location);
|
||||
CHECK(fv->optimized_code_weak_or_smi()->IsWeak());
|
||||
|
||||
|
@ -42,7 +42,7 @@ class InterpreterCallable {
|
||||
return CallInterpreter(isolate_, function_, args...);
|
||||
}
|
||||
|
||||
FeedbackVector* vector() const { return function_->feedback_vector(); }
|
||||
FeedbackVector vector() const { return function_->feedback_vector(); }
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
|
Loading…
Reference in New Issue
Block a user