[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:
Jakob Kummerow 2018-11-30 11:58:04 -08:00 committed by Commit Bot
parent 9f6a854a7b
commit f53d4d70a9
32 changed files with 90 additions and 86 deletions

View File

@ -601,7 +601,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache(
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
if (osr_offset.IsNone()) { if (osr_offset.IsNone()) {
if (function->feedback_cell()->value()->IsFeedbackVector()) { if (function->feedback_cell()->value()->IsFeedbackVector()) {
FeedbackVector* feedback_vector = function->feedback_vector(); FeedbackVector feedback_vector = function->feedback_vector();
feedback_vector->EvictOptimizedCodeMarkedForDeoptimization( feedback_vector->EvictOptimizedCodeMarkedForDeoptimization(
function->shared(), "GetCodeFromOptimizedCodeCache"); function->shared(), "GetCodeFromOptimizedCodeCache");
Code code = feedback_vector->optimized_code(); Code code = feedback_vector->optimized_code();

View File

@ -499,7 +499,7 @@ std::unique_ptr<Coverage> Coverage::Collect(
Handle<ArrayList> list = Handle<ArrayList>::cast( Handle<ArrayList> list = Handle<ArrayList>::cast(
isolate->factory()->feedback_vectors_for_profiling_tools()); isolate->factory()->feedback_vectors_for_profiling_tools());
for (int i = 0; i < list->Length(); i++) { 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(); SharedFunctionInfo shared = vector->shared_function_info();
DCHECK(shared->IsSubjectToDebugging()); DCHECK(shared->IsSubjectToDebugging());
uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 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()); HeapIterator heap_iterator(isolate->heap());
while (HeapObject* current_obj = heap_iterator.next()) { while (HeapObject* current_obj = heap_iterator.next()) {
if (!current_obj->IsFeedbackVector()) continue; if (!current_obj->IsFeedbackVector()) continue;
FeedbackVector* vector = FeedbackVector::cast(current_obj); FeedbackVector vector = FeedbackVector::cast(current_obj);
SharedFunctionInfo shared = vector->shared_function_info(); SharedFunctionInfo shared = vector->shared_function_info();
if (!shared->IsSubjectToDebugging()) continue; if (!shared->IsSubjectToDebugging()) continue;
uint32_t count = static_cast<uint32_t>(vector->invocation_count()); 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); shared->set_has_reported_binary_coverage(false);
} else if (o->IsFeedbackVector()) { } else if (o->IsFeedbackVector()) {
// In any case, clear any collected invocation counts. // In any case, clear any collected invocation counts.
FeedbackVector* vector = FeedbackVector::cast(o); FeedbackVector::cast(o)->clear_invocation_count();
vector->clear_invocation_count();
} }
} }

View File

@ -37,7 +37,7 @@ std::unique_ptr<TypeProfile> TypeProfile::Collect(Isolate* isolate) {
// TODO(franzih): Sort the vectors by script first instead of iterating // TODO(franzih): Sort the vectors by script first instead of iterating
// the list multiple times. // the list multiple times.
for (int i = 0; i < list->Length(); i++) { 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(); SharedFunctionInfo info = vector->shared_function_info();
DCHECK(info->IsSubjectToDebugging()); DCHECK(info->IsSubjectToDebugging());
@ -86,7 +86,7 @@ void TypeProfile::SelectMode(Isolate* isolate, debug::TypeProfile::Mode mode) {
isolate->factory()->feedback_vectors_for_profiling_tools()); isolate->factory()->feedback_vectors_for_profiling_tools());
for (int i = 0; i < list->Length(); i++) { 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(); SharedFunctionInfo info = vector->shared_function_info();
DCHECK(info->IsSubjectToDebugging()); DCHECK(info->IsSubjectToDebugging());
if (info->feedback_metadata()->HasTypeProfileSlot()) { if (info->feedback_metadata()->HasTypeProfileSlot()) {

View File

@ -3422,10 +3422,10 @@ void TranslatedState::Init(Isolate* isolate, Address input_frame_pointer,
void TranslatedState::Prepare(Address stack_frame_pointer) { void TranslatedState::Prepare(Address stack_frame_pointer) {
for (auto& frame : frames_) frame.Handlify(); for (auto& frame : frames_) frame.Handlify();
if (feedback_vector_ != nullptr) { if (!feedback_vector_.is_null()) {
feedback_vector_handle_ = feedback_vector_handle_ =
Handle<FeedbackVector>(feedback_vector_, isolate()); Handle<FeedbackVector>(feedback_vector_, isolate());
feedback_vector_ = nullptr; feedback_vector_ = FeedbackVector();
} }
stack_frame_pointer_ = stack_frame_pointer; stack_frame_pointer_ = stack_frame_pointer;

View File

@ -397,7 +397,7 @@ class TranslatedState {
}; };
std::deque<ObjectPosition> object_positions_; std::deque<ObjectPosition> object_positions_;
Handle<FeedbackVector> feedback_vector_handle_; Handle<FeedbackVector> feedback_vector_handle_;
FeedbackVector* feedback_vector_ = nullptr; FeedbackVector feedback_vector_;
FeedbackSlot feedback_slot_; FeedbackSlot feedback_slot_;
}; };

View File

@ -20,6 +20,14 @@
namespace v8 { namespace v8 {
namespace internal { 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_ACCESSORS(FeedbackMetadata, slot_count, kSlotCountOffset)
int32_t FeedbackMetadata::synchronized_slot_count() const { int32_t FeedbackMetadata::synchronized_slot_count() const {
@ -27,12 +35,6 @@ int32_t FeedbackMetadata::synchronized_slot_count() const {
FIELD_ADDR(this, kSlotCountOffset))); 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 { int32_t FeedbackMetadata::get(int index) const {
DCHECK(index >= 0 && index < length()); DCHECK(index >= 0 && index < length());
int offset = kHeaderSize + index * kInt32Size; int offset = kHeaderSize + index * kInt32Size;
@ -51,12 +53,6 @@ int FeedbackMetadata::length() const {
return FeedbackMetadata::length(slot_count()); return FeedbackMetadata::length(slot_count());
} }
// static
FeedbackVector* FeedbackVector::cast(Object* obj) {
DCHECK(obj->IsFeedbackVector());
return reinterpret_cast<FeedbackVector*>(obj);
}
int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) { int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
switch (kind) { switch (kind) {
case FeedbackSlotKind::kForIn: case FeedbackSlotKind::kForIn:
@ -103,7 +99,7 @@ INT32_ACCESSORS(FeedbackVector, deopt_count, kDeoptCountOffset)
bool FeedbackVector::is_empty() const { return length() == 0; } bool FeedbackVector::is_empty() const { return length() == 0; }
FeedbackMetadata* FeedbackVector::metadata() const { FeedbackMetadata FeedbackVector::metadata() const {
return shared_function_info()->feedback_metadata(); return shared_function_info()->feedback_metadata();
} }
@ -180,7 +176,7 @@ void FeedbackVector::set(int index, Object* value, WriteBarrierMode mode) {
} }
inline MaybeObjectSlot FeedbackVector::slots_start() { inline MaybeObjectSlot FeedbackVector::slots_start() {
return HeapObject::RawMaybeWeakField(this, kFeedbackSlotsOffset); return RawMaybeWeakField(kFeedbackSlotsOffset);
} }
// Helper function to transform the feedback to BinaryOperationHint. // Helper function to transform the feedback to BinaryOperationHint.

View File

@ -364,7 +364,7 @@ bool FeedbackVector::ClearSlots(Isolate* isolate) {
MaybeObject obj = Get(slot); MaybeObject obj = Get(slot);
if (obj != uninitialized_sentinel) { if (obj != uninitialized_sentinel) {
FeedbackNexus nexus(this, slot); FeedbackNexus nexus(*this, slot);
feedback_updated |= nexus.Clear(); feedback_updated |= nexus.Clear();
} }
} }

View File

@ -13,10 +13,12 @@
#include "src/globals.h" #include "src/globals.h"
#include "src/objects/map.h" #include "src/objects/map.h"
#include "src/objects/name.h" #include "src/objects/name.h"
#include "src/objects/object-macros.h"
#include "src/type-hints.h" #include "src/type-hints.h"
#include "src/zone/zone-containers.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 v8 {
namespace internal { namespace internal {
@ -145,17 +147,18 @@ class FeedbackMetadata;
// - optimized code cell (weak cell or Smi marker) // - optimized code cell (weak cell or Smi marker)
// followed by an array of feedback slots, of length determined by the feedback // followed by an array of feedback slots, of length determined by the feedback
// metadata. // metadata.
class FeedbackVector : public HeapObject, public NeverReadOnlySpaceObject { class FeedbackVector : public HeapObjectPtr {
public: public:
// Casting. NEVER_READ_ONLY_SPACE
static inline FeedbackVector* cast(Object* obj);
DECL_CAST2(FeedbackVector)
inline void ComputeCounts(int* with_type_info, int* generic, inline void ComputeCounts(int* with_type_info, int* generic,
int* vector_ic_count); int* vector_ic_count);
inline bool is_empty() const; 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 // [shared_function_info]: The shared function info for the function with this
// feedback vector. // feedback vector.
@ -303,7 +306,7 @@ class FeedbackVector : public HeapObject, public NeverReadOnlySpaceObject {
static void AddToVectorsForProfilingTools(Isolate* isolate, static void AddToVectorsForProfilingTools(Isolate* isolate,
Handle<FeedbackVector> vector); Handle<FeedbackVector> vector);
DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackVector); OBJECT_CONSTRUCTORS(FeedbackVector, HeapObjectPtr);
}; };
class V8_EXPORT_PRIVATE FeedbackVectorSpec { class V8_EXPORT_PRIVATE FeedbackVectorSpec {
@ -448,10 +451,9 @@ class SharedFeedbackSlot {
// of int32 data. The length is never stored - it is always calculated from // 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 // slot_count. All instances are created through the static New function, and
// the number of slots is static once an instance is created. // the number of slots is static once an instance is created.
class FeedbackMetadata : public HeapObject { class FeedbackMetadata : public HeapObjectPtr {
public: public:
// Casting. DECL_CAST2(FeedbackMetadata)
static inline FeedbackMetadata* cast(Object* obj);
// The number of slots that this metadata contains. Stored as an int32. // The number of slots that this metadata contains. Stored as an int32.
DECL_INT32_ACCESSORS(slot_count) DECL_INT32_ACCESSORS(slot_count)
@ -515,7 +517,7 @@ class FeedbackMetadata : public HeapObject {
kInt32Size * kBitsPerByte, uint32_t> kInt32Size * kBitsPerByte, uint32_t>
VectorICComputer; VectorICComputer;
DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackMetadata); OBJECT_CONSTRUCTORS(FeedbackMetadata, HeapObjectPtr);
}; };
// Verify that an empty hash field looks like a tagged object, but can't // Verify that an empty hash field looks like a tagged object, but can't
@ -532,7 +534,7 @@ class FeedbackMetadataIterator {
next_slot_(FeedbackSlot(0)), next_slot_(FeedbackSlot(0)),
slot_kind_(FeedbackSlotKind::kInvalid) {} slot_kind_(FeedbackSlotKind::kInvalid) {}
explicit FeedbackMetadataIterator(FeedbackMetadata* metadata) explicit FeedbackMetadataIterator(FeedbackMetadata metadata)
: metadata_(metadata), : metadata_(metadata),
next_slot_(FeedbackSlot(0)), next_slot_(FeedbackSlot(0)),
slot_kind_(FeedbackSlotKind::kInvalid) {} slot_kind_(FeedbackSlotKind::kInvalid) {}
@ -552,7 +554,7 @@ class FeedbackMetadataIterator {
inline int entry_size() const; inline int entry_size() const;
private: private:
FeedbackMetadata* metadata() const { FeedbackMetadata metadata() const {
return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_; 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 // to have a single iterator implementation for both "handlified" and raw
// pointer use cases. // pointer use cases.
Handle<FeedbackMetadata> metadata_handle_; Handle<FeedbackMetadata> metadata_handle_;
FeedbackMetadata* metadata_; FeedbackMetadata metadata_;
FeedbackSlot cur_slot_; FeedbackSlot cur_slot_;
FeedbackSlot next_slot_; FeedbackSlot next_slot_;
FeedbackSlotKind slot_kind_; FeedbackSlotKind slot_kind_;
@ -571,17 +573,16 @@ class FeedbackNexus final {
public: public:
FeedbackNexus(Handle<FeedbackVector> vector, FeedbackSlot slot) FeedbackNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
: vector_handle_(vector), : vector_handle_(vector),
vector_(nullptr),
slot_(slot), slot_(slot),
kind_(vector->GetKind(slot)) {} kind_(vector->GetKind(slot)) {}
FeedbackNexus(FeedbackVector* vector, FeedbackSlot slot) FeedbackNexus(FeedbackVector vector, FeedbackSlot slot)
: vector_(vector), slot_(slot), kind_(vector->GetKind(slot)) {} : vector_(vector), slot_(slot), kind_(vector->GetKind(slot)) {}
Handle<FeedbackVector> vector_handle() const { Handle<FeedbackVector> vector_handle() const {
DCHECK_NULL(vector_); DCHECK(vector_.is_null());
return vector_handle_; return vector_handle_;
} }
FeedbackVector* vector() const { FeedbackVector vector() const {
return vector_handle_.is_null() ? vector_ : *vector_handle_; return vector_handle_.is_null() ? vector_ : *vector_handle_;
} }
FeedbackSlot slot() const { return slot_; } 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 // you have a handle to the vector that is better because more operations can
// be done, like allocation. // be done, like allocation.
Handle<FeedbackVector> vector_handle_; Handle<FeedbackVector> vector_handle_;
FeedbackVector* vector_; FeedbackVector vector_;
FeedbackSlot slot_; FeedbackSlot slot_;
FeedbackSlotKind kind_; FeedbackSlotKind kind_;
}; };
@ -726,4 +727,6 @@ inline ForInHint ForInHintFromFeedback(int type_feedback);
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_FEEDBACK_VECTOR_H_ #endif // V8_FEEDBACK_VECTOR_H_

View File

@ -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, ByteArray>::value || std::is_same<S, Code>::value ||
std::is_same<S, Context>::value || std::is_same<S, Context>::value ||
std::is_same<S, DescriptorArray>::value || std::is_same<S, DescriptorArray>::value ||
std::is_same<S, FeedbackVector>::value ||
std::is_same<S, FixedArray>::value || std::is_same<S, FixedArray>::value ||
std::is_same<S, FixedArrayBase>::value || std::is_same<S, FixedArrayBase>::value ||
std::is_same<S, FixedDoubleArray>::value || std::is_same<S, FixedDoubleArray>::value ||

View File

@ -3634,8 +3634,9 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
// from a FunctionLiteral. Those can just reset this field to keep the // from a FunctionLiteral. Those can just reset this field to keep the
// SharedFunctionInfo in a consistent state. // SharedFunctionInfo in a consistent state.
if (maybe_builtin_index == Builtins::kCompileLazy) { if (maybe_builtin_index == Builtins::kCompileLazy) {
share->set_raw_outer_scope_info_or_feedback_metadata(*the_hole_value(), // TODO(3770): Drop explicit cast when migrating Oddball*.
SKIP_WRITE_BARRIER); share->set_raw_outer_scope_info_or_feedback_metadata(
HeapObjectPtr::cast(*the_hole_value()), SKIP_WRITE_BARRIER);
} else { } else {
share->set_raw_outer_scope_info_or_feedback_metadata( share->set_raw_outer_scope_info_or_feedback_metadata(
*empty_feedback_metadata(), SKIP_WRITE_BARRIER); *empty_feedback_metadata(), SKIP_WRITE_BARRIER);

View File

@ -378,7 +378,7 @@ class ObjectStatsCollectorImpl {
void RecordVirtualBytecodeArrayDetails(BytecodeArray bytecode); void RecordVirtualBytecodeArrayDetails(BytecodeArray bytecode);
void RecordVirtualCodeDetails(Code code); void RecordVirtualCodeDetails(Code code);
void RecordVirtualContext(Context context); void RecordVirtualContext(Context context);
void RecordVirtualFeedbackVectorDetails(FeedbackVector* vector); void RecordVirtualFeedbackVectorDetails(FeedbackVector vector);
void RecordVirtualFixedArrayDetails(FixedArray array); void RecordVirtualFixedArrayDetails(FixedArray array);
void RecordVirtualFunctionTemplateInfoDetails(FunctionTemplateInfo* fti); void RecordVirtualFunctionTemplateInfoDetails(FunctionTemplateInfo* fti);
void RecordVirtualJSGlobalObjectDetails(JSGlobalObject* object); void RecordVirtualJSGlobalObjectDetails(JSGlobalObject* object);
@ -595,7 +595,7 @@ static ObjectStats::VirtualInstanceType GetFeedbackSlotType(
} }
void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails( void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
FeedbackVector* vector) { FeedbackVector vector) {
if (virtual_objects_.find(vector) == virtual_objects_.end()) { if (virtual_objects_.find(vector) == virtual_objects_.end()) {
// Manually insert the feedback vector into the virtual object list, since // Manually insert the feedback vector into the virtual object list, since
// we're logging its component parts separately. // we're logging its component parts separately.

View File

@ -47,7 +47,7 @@ class WasmInstanceObject;
V(EmbedderDataArray, EmbedderDataArray) \ V(EmbedderDataArray, EmbedderDataArray) \
V(EphemeronHashTable, EphemeronHashTable) \ V(EphemeronHashTable, EphemeronHashTable) \
V(FeedbackCell, FeedbackCell*) \ V(FeedbackCell, FeedbackCell*) \
V(FeedbackVector, FeedbackVector*) \ V(FeedbackVector, FeedbackVector) \
V(FixedArray, FixedArray) \ V(FixedArray, FixedArray) \
V(FixedDoubleArray, FixedDoubleArray) \ V(FixedDoubleArray, FixedDoubleArray) \
V(FixedFloat64Array, FixedFloat64Array) \ V(FixedFloat64Array, FixedFloat64Array) \

View File

@ -311,13 +311,13 @@ MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) {
// static // static
void IC::OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus, void IC::OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus,
JSFunction* host_function, const char* reason) { JSFunction* host_function, const char* reason) {
FeedbackVector* vector = nexus->vector(); FeedbackVector vector = nexus->vector();
FeedbackSlot slot = nexus->slot(); FeedbackSlot slot = nexus->slot();
OnFeedbackChanged(isolate, vector, slot, host_function, reason); OnFeedbackChanged(isolate, vector, slot, host_function, reason);
} }
// static // static
void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector, void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector vector,
FeedbackSlot slot, JSFunction* host_function, FeedbackSlot slot, JSFunction* host_function,
const char* reason) { const char* reason) {
if (FLAG_trace_opt_verbose) { if (FLAG_trace_opt_verbose) {

View File

@ -62,7 +62,7 @@ class IC {
static inline bool IsHandler(MaybeObject object); static inline bool IsHandler(MaybeObject object);
// Nofity the IC system that a feedback has changed. // 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, FeedbackSlot slot, JSFunction* host_function,
const char* reason); const char* reason);

View File

@ -3566,7 +3566,7 @@ void Isolate::MaybeInitializeVectorListFromHeap() {
while (HeapObject* current_obj = heap_iterator.next()) { while (HeapObject* current_obj = heap_iterator.next()) {
if (!current_obj->IsFeedbackVector()) continue; if (!current_obj->IsFeedbackVector()) continue;
FeedbackVector* vector = FeedbackVector::cast(current_obj); FeedbackVector vector = FeedbackVector::cast(current_obj);
SharedFunctionInfo shared = vector->shared_function_info(); SharedFunctionInfo shared = vector->shared_function_info();
// No need to preserve the feedback vector for non-user-visible functions. // No need to preserve the feedback vector for non-user-visible functions.

View File

@ -767,9 +767,9 @@ void NativeContext::NativeContextVerify(Isolate* isolate) {
void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) { void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) {
if (slot_count() == 0) { if (slot_count() == 0) {
CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), this); CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), *this);
} else { } else {
FeedbackMetadataIterator iter(this); FeedbackMetadataIterator iter(*this);
while (iter.HasNext()) { while (iter.HasNext()) {
iter.Next(); iter.Next();
FeedbackSlotKind kind = iter.kind(); FeedbackSlotKind kind = iter.kind();

View File

@ -1564,8 +1564,7 @@ int HeapObject::SizeFromMap(Map map) const {
} }
if (instance_type == FEEDBACK_METADATA_TYPE) { if (instance_type == FEEDBACK_METADATA_TYPE) {
return FeedbackMetadata::SizeFor( return FeedbackMetadata::SizeFor(
reinterpret_cast<const FeedbackMetadata*>(this) FeedbackMetadata::unchecked_cast(this)->synchronized_slot_count());
->synchronized_slot_count());
} }
if (instance_type == DESCRIPTOR_ARRAY_TYPE) { if (instance_type == DESCRIPTOR_ARRAY_TYPE) {
return DescriptorArray::SizeFor( return DescriptorArray::SizeFor(
@ -1603,7 +1602,7 @@ int HeapObject::SizeFromMap(Map map) const {
} }
if (instance_type == FEEDBACK_VECTOR_TYPE) { if (instance_type == FEEDBACK_VECTOR_TYPE) {
return FeedbackVector::SizeFor( return FeedbackVector::SizeFor(
reinterpret_cast<const FeedbackVector*>(this)->length()); FeedbackVector::unchecked_cast(this)->length());
} }
if (instance_type == BIGINT_TYPE) { if (instance_type == BIGINT_TYPE) {
return BigInt::SizeFor(BigInt::unchecked_cast(this)->length()); return BigInt::SizeFor(BigInt::unchecked_cast(this)->length());

View File

@ -1054,10 +1054,10 @@ void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) { // NOLINT
} }
void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) { void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
HeapObject::PrintHeader(os, "FeedbackMetadata"); PrintHeader(os, "FeedbackMetadata");
os << "\n - slot_count: " << slot_count(); os << "\n - slot_count: " << slot_count();
FeedbackMetadataIterator iter(this); FeedbackMetadataIterator iter(*this);
while (iter.HasNext()) { while (iter.HasNext()) {
FeedbackSlot slot = iter.Next(); FeedbackSlot slot = iter.Next();
FeedbackSlotKind kind = iter.kind(); FeedbackSlotKind kind = iter.kind();
@ -1067,7 +1067,7 @@ void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
} }
void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
HeapObject::PrintHeader(os, "FeedbackVector"); PrintHeader(os, "FeedbackVector");
os << "\n - length: " << length(); os << "\n - length: " << length();
if (length() == 0) { if (length() == 0) {
os << " (empty)\n"; os << " (empty)\n";
@ -1105,7 +1105,7 @@ void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
void FeedbackVector::FeedbackSlotPrint(std::ostream& os, void FeedbackVector::FeedbackSlotPrint(std::ostream& os,
FeedbackSlot slot) { // NOLINT FeedbackSlot slot) { // NOLINT
FeedbackNexus nexus(this, slot); FeedbackNexus nexus(*this, slot);
nexus.Print(os); nexus.Print(os);
} }

View File

@ -14685,7 +14685,7 @@ int AbstractCode::SourceStatementPosition(int offset) {
void JSFunction::ClearTypeFeedbackInfo() { void JSFunction::ClearTypeFeedbackInfo() {
if (feedback_cell()->value()->IsFeedbackVector()) { if (feedback_cell()->value()->IsFeedbackVector()) {
FeedbackVector* vector = feedback_vector(); FeedbackVector vector = feedback_vector();
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
if (vector->ClearSlots(isolate)) { if (vector->ClearSlots(isolate)) {
IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(), this, IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(), this,

View File

@ -110,6 +110,8 @@ HeapObjectPtr::HeapObjectPtr(Address ptr, AllowInlineSmiStorage allow_smi)
IsHeapObject()); IsHeapObject());
} }
CAST_ACCESSOR2(HeapObjectPtr)
#define TYPE_CHECK_FORWARDER(Type) \ #define TYPE_CHECK_FORWARDER(Type) \
bool HeapObjectPtr::Is##Type() const { \ bool HeapObjectPtr::Is##Type() const { \
return reinterpret_cast<HeapObject*>(ptr())->Is##Type(); \ return reinterpret_cast<HeapObject*>(ptr())->Is##Type(); \

View File

@ -211,6 +211,8 @@ class HeapObjectPtr : public ObjectPtr {
inline Address GetFieldAddress(int field_offset) const; inline Address GetFieldAddress(int field_offset) const;
DECL_CAST2(HeapObjectPtr)
protected: protected:
// Special-purpose constructor for subclasses that have fast paths where // Special-purpose constructor for subclasses that have fast paths where
// their ptr() is a Smi. // their ptr() is a Smi.

View File

@ -429,7 +429,7 @@ ACCESSORS(JSGlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset) ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
FeedbackVector* JSFunction::feedback_vector() const { FeedbackVector JSFunction::feedback_vector() const {
DCHECK(has_feedback_vector()); DCHECK(has_feedback_vector());
return FeedbackVector::cast(feedback_cell()->value()); return FeedbackVector::cast(feedback_cell()->value());
} }

View File

@ -990,7 +990,7 @@ class JSFunction : public JSObject {
DECL_ACCESSORS(feedback_cell, FeedbackCell) DECL_ACCESSORS(feedback_cell, FeedbackCell)
// feedback_vector() can be used once the function is compiled. // 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; inline bool has_feedback_vector() const;
static void EnsureFeedbackVector(Handle<JSFunction> function); static void EnsureFeedbackVector(Handle<JSFunction> function);

View File

@ -311,10 +311,10 @@ void SharedFunctionInfo::set_scope_info(ScopeInfo scope_info,
CONDITIONAL_WRITE_BARRIER(this, kNameOrScopeInfoOffset, scope_info, mode); CONDITIONAL_WRITE_BARRIER(this, kNameOrScopeInfoOffset, scope_info, mode);
} }
ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata, ACCESSORS2(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset) HeapObjectPtr, kOuterScopeInfoOrFeedbackMetadataOffset)
HeapObject* SharedFunctionInfo::outer_scope_info() const { HeapObjectPtr SharedFunctionInfo::outer_scope_info() const {
DCHECK(!is_compiled()); DCHECK(!is_compiled());
DCHECK(!HasFeedbackMetadata()); DCHECK(!HasFeedbackMetadata());
return raw_outer_scope_info_or_feedback_metadata(); return raw_outer_scope_info_or_feedback_metadata();
@ -338,28 +338,28 @@ ScopeInfo SharedFunctionInfo::GetOuterScopeInfo() const {
return scope_info()->OuterScopeInfo(); return scope_info()->OuterScopeInfo();
} }
void SharedFunctionInfo::set_outer_scope_info(HeapObject* value, void SharedFunctionInfo::set_outer_scope_info(HeapObjectPtr value,
WriteBarrierMode mode) { WriteBarrierMode mode) {
DCHECK(!is_compiled()); DCHECK(!is_compiled());
DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole()); DCHECK(raw_outer_scope_info_or_feedback_metadata()->IsTheHole());
DCHECK(value->IsScopeInfo() || value->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 { bool SharedFunctionInfo::HasFeedbackMetadata() const {
return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata(); return raw_outer_scope_info_or_feedback_metadata()->IsFeedbackMetadata();
} }
FeedbackMetadata* SharedFunctionInfo::feedback_metadata() const { FeedbackMetadata SharedFunctionInfo::feedback_metadata() const {
DCHECK(HasFeedbackMetadata()); DCHECK(HasFeedbackMetadata());
return FeedbackMetadata::cast(raw_outer_scope_info_or_feedback_metadata()); 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) { WriteBarrierMode mode) {
DCHECK(!HasFeedbackMetadata()); DCHECK(!HasFeedbackMetadata());
DCHECK(value->IsFeedbackMetadata()); 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 { bool SharedFunctionInfo::is_compiled() const {
@ -653,11 +653,13 @@ void SharedFunctionInfo::DiscardCompiled(
if (shared_info->is_compiled()) { if (shared_info->is_compiled()) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
HeapObject* outer_scope_info; HeapObjectPtr outer_scope_info;
if (shared_info->scope_info()->HasOuterScopeInfo()) { if (shared_info->scope_info()->HasOuterScopeInfo()) {
outer_scope_info = shared_info->scope_info()->OuterScopeInfo(); outer_scope_info = shared_info->scope_info()->OuterScopeInfo();
} else { } 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 // Raw setter to avoid validity checks, since we're performing the unusual
// task of decompiling. // task of decompiling.

View File

@ -235,7 +235,7 @@ class SharedFunctionInfo : public HeapObjectPtr {
// [outer scope info | feedback metadata] Shared storage for outer scope info // [outer scope info | feedback metadata] Shared storage for outer scope info
// (on uncompiled functions) and feedback metadata (on compiled functions). // (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. // Get the outer scope info whether this function is compiled or not.
inline bool HasOuterScopeInfo() const; inline bool HasOuterScopeInfo() const;
@ -244,7 +244,7 @@ class SharedFunctionInfo : public HeapObjectPtr {
// [feedback metadata] Metadata template for feedback vectors of instances of // [feedback metadata] Metadata template for feedback vectors of instances of
// this function. // this function.
inline bool HasFeedbackMetadata() const; 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. // Returns if this function has been compiled to native code yet.
inline bool is_compiled() const; 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 // [outer scope info] The outer scope info, needed to lazily parse this
// function. // function.
DECL_ACCESSORS(outer_scope_info, HeapObject) DECL_ACCESSORS2(outer_scope_info, HeapObjectPtr)
inline void set_kind(FunctionKind kind); inline void set_kind(FunctionKind kind);

View File

@ -1233,7 +1233,7 @@ void V8HeapExplorer::ExtractFixedArrayReferences(HeapEntry* entry,
} }
void V8HeapExplorer::ExtractFeedbackVectorReferences( void V8HeapExplorer::ExtractFeedbackVectorReferences(
HeapEntry* entry, FeedbackVector* feedback_vector) { HeapEntry* entry, FeedbackVector feedback_vector) {
MaybeObject code = feedback_vector->optimized_code_weak_or_smi(); MaybeObject code = feedback_vector->optimized_code_weak_or_smi();
HeapObject* code_heap_object; HeapObject* code_heap_object;
if (code->GetHeapObjectIfWeak(&code_heap_object)) { if (code->GetHeapObjectIfWeak(&code_heap_object)) {

View File

@ -377,7 +377,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
JSGeneratorObject* generator); JSGeneratorObject* generator);
void ExtractFixedArrayReferences(HeapEntry* entry, FixedArray array); void ExtractFixedArrayReferences(HeapEntry* entry, FixedArray array);
void ExtractFeedbackVectorReferences(HeapEntry* entry, void ExtractFeedbackVectorReferences(HeapEntry* entry,
FeedbackVector* feedback_vector); FeedbackVector feedback_vector);
void ExtractDescriptorArrayReferences(HeapEntry* entry, void ExtractDescriptorArrayReferences(HeapEntry* entry,
DescriptorArray array); DescriptorArray array);
template <typename T> template <typename T>

View File

@ -202,7 +202,7 @@ class RootVisitor;
EmptySlowElementDictionary) \ EmptySlowElementDictionary) \
V(FixedArray, empty_ordered_hash_map, EmptyOrderedHashMap) \ V(FixedArray, empty_ordered_hash_map, EmptyOrderedHashMap) \
V(FixedArray, empty_ordered_hash_set, EmptyOrderedHashSet) \ 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(PropertyCell*, empty_property_cell, EmptyPropertyCell) \
V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \ V(NameDictionary, empty_property_dictionary, EmptyPropertyDictionary) \
V(InterceptorInfo*, noop_interceptor_info, NoOpInterceptorInfo) \ V(InterceptorInfo*, noop_interceptor_info, NoOpInterceptorInfo) \

View File

@ -73,8 +73,7 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
static void GetICCounts(JSFunction* function, int* ic_with_type_info_count, static void GetICCounts(JSFunction* function, int* ic_with_type_info_count,
int* ic_generic_count, int* ic_total_count, int* ic_generic_count, int* ic_total_count,
int* type_info_percentage, int* generic_percentage) { 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, vector->ComputeCounts(ic_with_type_info_count, ic_generic_count,
ic_total_count); ic_total_count);

View File

@ -4393,7 +4393,7 @@ Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
void CheckIC(Handle<JSFunction> function, int slot_index, void CheckIC(Handle<JSFunction> function, int slot_index,
InlineCacheState state) { InlineCacheState state) {
FeedbackVector* vector = function->feedback_vector(); FeedbackVector vector = function->feedback_vector();
FeedbackSlot slot(slot_index); FeedbackSlot slot(slot_index);
FeedbackNexus nexus(vector, slot); FeedbackNexus nexus(vector, slot);
CHECK_EQ(nexus.StateFromFeedback(), state); CHECK_EQ(nexus.StateFromFeedback(), state);

View File

@ -193,7 +193,7 @@ TEST(ObjectMovesBeforeClearingWeakField) {
Handle<FeedbackVector> fv = Handle<FeedbackVector> fv =
CreateFeedbackVectorForTest(CcTest::isolate(), factory); CreateFeedbackVectorForTest(CcTest::isolate(), factory);
CHECK(Heap::InNewSpace(*fv)); CHECK(Heap::InNewSpace(*fv));
FeedbackVector* fv_location = *fv; FeedbackVector fv_location = *fv;
{ {
HandleScope inner_scope(isolate); HandleScope inner_scope(isolate);
// Create a new FixedArray which the FeedbackVector will point to. // Create a new FixedArray which the FeedbackVector will point to.
@ -210,7 +210,7 @@ TEST(ObjectMovesBeforeClearingWeakField) {
// Scavenger will move *fv. // Scavenger will move *fv.
CcTest::CollectGarbage(NEW_SPACE); CcTest::CollectGarbage(NEW_SPACE);
FeedbackVector* new_fv_location = *fv; FeedbackVector new_fv_location = *fv;
CHECK_NE(fv_location, new_fv_location); CHECK_NE(fv_location, new_fv_location);
CHECK(fv->optimized_code_weak_or_smi()->IsWeak()); CHECK(fv->optimized_code_weak_or_smi()->IsWeak());

View File

@ -42,7 +42,7 @@ class InterpreterCallable {
return CallInterpreter(isolate_, function_, args...); return CallInterpreter(isolate_, function_, args...);
} }
FeedbackVector* vector() const { return function_->feedback_vector(); } FeedbackVector vector() const { return function_->feedback_vector(); }
private: private:
Isolate* isolate_; Isolate* isolate_;