Link type feedback vectors to the shared function info.
Previously, both type feedback vector and the shared function info of a function points to the matching type feedback metadata. This makes finding the shared function info of a type feedback vector difficult. Instead, we now point the type feeback vector to the shared function info, and find the metadata through the shared function info. Also remove the obsolete empty type feedback vector. R=hpayer@chromium.org, mvstanton@chromium.org BUG=v8:5808 Review-Url: https://codereview.chromium.org/2672363002 Cr-Commit-Position: refs/heads/master@{#43026}
This commit is contained in:
parent
6516074960
commit
c78d7fa1ae
@ -28,7 +28,6 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
|
||||
V(CodeMap, CodeMap) \
|
||||
V(empty_string, EmptyString) \
|
||||
V(EmptyFixedArray, EmptyFixedArray) \
|
||||
V(EmptyFeedbackVector, EmptyFeedbackVector) \
|
||||
V(FalseValue, False) \
|
||||
V(FixedArrayMap, FixedArrayMap) \
|
||||
V(FixedCOWArrayMap, FixedCOWArrayMap) \
|
||||
|
@ -1587,8 +1587,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
|
||||
// Promote to per-isolate compilation cache.
|
||||
// TODO(mvstanton): create a feedback vector array here.
|
||||
DCHECK(inner_result->is_compiled());
|
||||
Handle<FeedbackVector> feedback_vector = FeedbackVector::New(
|
||||
isolate, handle(inner_result->feedback_metadata()));
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
FeedbackVector::New(isolate, inner_result);
|
||||
vector = isolate->factory()->NewCell(feedback_vector);
|
||||
compilation_cache->PutScript(source, context, language_mode,
|
||||
inner_result, vector);
|
||||
@ -1662,7 +1662,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
|
||||
// We need a feedback vector.
|
||||
DCHECK(result->is_compiled());
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
FeedbackVector::New(isolate, handle(result->feedback_metadata()));
|
||||
FeedbackVector::New(isolate, result);
|
||||
vector = isolate->factory()->NewCell(feedback_vector);
|
||||
compilation_cache->PutScript(source, context, language_mode, result,
|
||||
vector);
|
||||
|
@ -758,17 +758,15 @@ class FeedbackVectorFixer {
|
||||
// collect all functions and fix their literal arrays.
|
||||
Handle<FixedArray> function_instances =
|
||||
CollectJSFunctions(shared_info, isolate);
|
||||
Handle<FeedbackMetadata> feedback_metadata(
|
||||
shared_info->feedback_metadata());
|
||||
|
||||
for (int i = 0; i < function_instances->length(); i++) {
|
||||
Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
|
||||
Handle<FeedbackVector> vector =
|
||||
FeedbackVector::New(isolate, feedback_metadata);
|
||||
fun->feedback_vector_cell()->set_value(*vector);
|
||||
}
|
||||
fun->set_feedback_vector_cell(isolate->heap()->undefined_cell());
|
||||
// Only create feedback vectors if we already have the metadata.
|
||||
if (shared_info->is_compiled()) JSFunction::EnsureLiterals(fun);
|
||||
}
|
||||
|
||||
shared_info->set_num_literals(new_literal_count);
|
||||
shared_info->set_num_literals(new_literal_count);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -925,6 +923,9 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
Handle<FeedbackMetadata> new_feedback_metadata(
|
||||
new_shared_info->feedback_metadata());
|
||||
shared_info->set_feedback_metadata(*new_feedback_metadata);
|
||||
} else {
|
||||
shared_info->set_feedback_metadata(
|
||||
FeedbackMetadata::cast(isolate->heap()->empty_fixed_array()));
|
||||
}
|
||||
|
||||
int start_position = compile_info_wrapper.GetStartPosition();
|
||||
|
@ -84,7 +84,11 @@ int FeedbackVector::slot_count() const {
|
||||
}
|
||||
|
||||
FeedbackMetadata* FeedbackVector::metadata() const {
|
||||
return FeedbackMetadata::cast(get(kMetadataIndex));
|
||||
return shared_function_info()->feedback_metadata();
|
||||
}
|
||||
|
||||
SharedFunctionInfo* FeedbackVector::shared_function_info() const {
|
||||
return SharedFunctionInfo::cast(get(kSharedFunctionInfoIndex));
|
||||
}
|
||||
|
||||
int FeedbackVector::invocation_count() const {
|
||||
|
@ -161,18 +161,15 @@ FeedbackSlotKind FeedbackVector::GetKind(FeedbackSlot slot) const {
|
||||
|
||||
// static
|
||||
Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
Handle<FeedbackMetadata> metadata) {
|
||||
Handle<SharedFunctionInfo> shared) {
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
const int slot_count = metadata->slot_count();
|
||||
const int slot_count = shared->feedback_metadata()->slot_count();
|
||||
const int length = slot_count + kReservedIndexCount;
|
||||
if (length == kReservedIndexCount) {
|
||||
return Handle<FeedbackVector>::cast(factory->empty_feedback_vector());
|
||||
}
|
||||
|
||||
Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
|
||||
array->set_map_no_write_barrier(isolate->heap()->feedback_vector_map());
|
||||
array->set(kMetadataIndex, *metadata);
|
||||
array->set(kSharedFunctionInfoIndex, *shared);
|
||||
array->set(kInvocationCountIndex, Smi::kZero);
|
||||
|
||||
// Ensure we can skip the write barrier
|
||||
@ -181,7 +178,7 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
|
||||
Handle<Oddball> undefined_value = factory->undefined_value();
|
||||
for (int i = 0; i < slot_count;) {
|
||||
FeedbackSlot slot(i);
|
||||
FeedbackSlotKind kind = metadata->GetKind(slot);
|
||||
FeedbackSlotKind kind = shared->feedback_metadata()->GetKind(slot);
|
||||
int index = FeedbackVector::GetIndex(slot);
|
||||
int entry_size = FeedbackMetadata::GetSlotSize(kind);
|
||||
|
||||
@ -253,8 +250,6 @@ void FeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
|
||||
Isolate* isolate = GetIsolate();
|
||||
if (!force_clear && !ClearLogic(isolate)) return;
|
||||
|
||||
if (this == isolate->heap()->empty_feedback_vector()) return;
|
||||
|
||||
Object* uninitialized_sentinel =
|
||||
FeedbackVector::RawUninitializedSentinel(isolate);
|
||||
Oddball* undefined_value = isolate->heap()->undefined_value();
|
||||
|
@ -263,7 +263,7 @@ class FeedbackVector : public FixedArray {
|
||||
// Casting.
|
||||
static inline FeedbackVector* cast(Object* obj);
|
||||
|
||||
static const int kMetadataIndex = 0;
|
||||
static const int kSharedFunctionInfoIndex = 0;
|
||||
static const int kInvocationCountIndex = 1;
|
||||
static const int kReservedIndexCount = 2;
|
||||
|
||||
@ -276,6 +276,7 @@ class FeedbackVector : public FixedArray {
|
||||
inline int slot_count() const;
|
||||
|
||||
inline FeedbackMetadata* metadata() const;
|
||||
inline SharedFunctionInfo* shared_function_info() const;
|
||||
inline int invocation_count() const;
|
||||
|
||||
// Conversion from a slot to an integer index to the underlying array.
|
||||
@ -293,7 +294,7 @@ class FeedbackVector : public FixedArray {
|
||||
FeedbackSlotKind GetKind(FeedbackSlot slot) const;
|
||||
|
||||
static Handle<FeedbackVector> New(Isolate* isolate,
|
||||
Handle<FeedbackMetadata> metadata);
|
||||
Handle<SharedFunctionInfo> shared);
|
||||
|
||||
static Handle<FeedbackVector> Copy(Isolate* isolate,
|
||||
Handle<FeedbackVector> vector);
|
||||
|
@ -2755,23 +2755,6 @@ void Heap::CreateInitialObjects() {
|
||||
// Number of queued microtasks stored in Isolate::pending_microtask_count().
|
||||
set_microtask_queue(empty_fixed_array());
|
||||
|
||||
{
|
||||
// Create a canonical empty FeedbackVector, which is shared by all
|
||||
// functions that don't need actual type feedback slots. Note however
|
||||
// that all these functions will share the same invocation count, but
|
||||
// that shouldn't matter since we only use the invocation count to
|
||||
// relativize the absolute call counts, but we can only have call counts
|
||||
// if we have actual feedback slots.
|
||||
Handle<FixedArray> empty_feedback_vector =
|
||||
factory->NewFixedArray(FeedbackVector::kReservedIndexCount, TENURED);
|
||||
empty_feedback_vector->set(FeedbackVector::kMetadataIndex,
|
||||
empty_fixed_array());
|
||||
empty_feedback_vector->set(FeedbackVector::kInvocationCountIndex,
|
||||
Smi::kZero);
|
||||
empty_feedback_vector->set_map(feedback_vector_map());
|
||||
set_empty_feedback_vector(*empty_feedback_vector);
|
||||
}
|
||||
|
||||
{
|
||||
Handle<FixedArray> empty_sloppy_arguments_elements =
|
||||
factory->NewFixedArray(2, TENURED);
|
||||
@ -2938,7 +2921,6 @@ bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Heap::RootCanBeTreatedAsConstant(RootListIndex root_index) {
|
||||
return !RootCanBeWrittenAfterInitialization(root_index) &&
|
||||
!InNewSpace(root(root_index));
|
||||
|
@ -58,8 +58,8 @@ using v8::MemoryPressureLevel;
|
||||
V(Map, foreign_map, ForeignMap) \
|
||||
V(Map, heap_number_map, HeapNumberMap) \
|
||||
V(Map, transition_array_map, TransitionArrayMap) \
|
||||
V(Map, feedback_vector_map, FeedbackVectorMap) \
|
||||
V(ScopeInfo, empty_scope_info, EmptyScopeInfo) \
|
||||
V(FixedArray, empty_feedback_vector, EmptyFeedbackVector) \
|
||||
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
|
||||
V(DescriptorArray, empty_descriptor_array, EmptyDescriptorArray) \
|
||||
/* Entries beyond the first 32 */ \
|
||||
@ -93,7 +93,6 @@ using v8::MemoryPressureLevel;
|
||||
V(Map, external_map, ExternalMap) \
|
||||
V(Map, bytecode_array_map, BytecodeArrayMap) \
|
||||
V(Map, module_info_map, ModuleInfoMap) \
|
||||
V(Map, feedback_vector_map, FeedbackVectorMap) \
|
||||
/* String maps */ \
|
||||
V(Map, native_source_string_map, NativeSourceStringMap) \
|
||||
V(Map, string_map, StringMap) \
|
||||
|
@ -330,7 +330,6 @@ static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) {
|
||||
array->map() != heap->fixed_double_array_map() &&
|
||||
array != heap->empty_fixed_array() &&
|
||||
array != heap->empty_byte_array() &&
|
||||
array != heap->empty_feedback_vector() &&
|
||||
array != heap->empty_sloppy_arguments_elements() &&
|
||||
array != heap->empty_slow_element_dictionary() &&
|
||||
array != heap->empty_descriptor_array() &&
|
||||
|
@ -2644,9 +2644,7 @@ bool Isolate::Init(Deserializer* des) {
|
||||
|
||||
bootstrapper_->Initialize(create_heap_objects);
|
||||
builtins_.SetUp(this, create_heap_objects);
|
||||
if (create_heap_objects) {
|
||||
heap_.CreateFixedStubs();
|
||||
}
|
||||
if (create_heap_objects) heap_.CreateFixedStubs();
|
||||
|
||||
if (FLAG_log_internal_timer_events) {
|
||||
set_event_logger(Logger::DefaultEventLoggerSentinel);
|
||||
|
@ -6591,12 +6591,7 @@ void JSFunction::ReplaceCode(Code* code) {
|
||||
}
|
||||
|
||||
bool JSFunction::has_feedback_vector() const {
|
||||
SharedFunctionInfo* shared = this->shared();
|
||||
|
||||
return (feedback_vector_cell()->value() !=
|
||||
shared->GetIsolate()->heap()->empty_feedback_vector() ||
|
||||
(shared->feedback_metadata()->slot_count() == 0 &&
|
||||
shared->num_literals() == 0));
|
||||
return !feedback_vector_cell()->value()->IsUndefined(GetIsolate());
|
||||
}
|
||||
|
||||
Context* JSFunction::context() {
|
||||
|
@ -12120,7 +12120,7 @@ void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
|
||||
}
|
||||
// Top level code didn't get it's literals installed.
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
FeedbackVector::New(isolate, handle(shared->feedback_metadata()));
|
||||
FeedbackVector::New(isolate, shared);
|
||||
Handle<Cell> new_cell = isolate->factory()->NewCell(feedback_vector);
|
||||
function->set_feedback_vector_cell(*new_cell);
|
||||
} else if (!cell->value()->IsFeedbackVector() ||
|
||||
@ -12132,7 +12132,7 @@ void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
|
||||
reinterpret_cast<void*>(*function));
|
||||
}
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
FeedbackVector::New(isolate, handle(shared->feedback_metadata()));
|
||||
FeedbackVector::New(isolate, shared);
|
||||
// Re-get the feedback_vector() value as GC may have occurred.
|
||||
function->feedback_vector_cell()->set_value(*feedback_vector);
|
||||
} else {
|
||||
@ -12142,11 +12142,6 @@ void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
|
||||
reinterpret_cast<void*>(*function));
|
||||
}
|
||||
}
|
||||
|
||||
// No matter what, ensure some post-conditions.
|
||||
DCHECK(shared->feedback_metadata()->slot_count() != 0 ||
|
||||
function->feedback_vector() ==
|
||||
shared->GetIsolate()->heap()->empty_feedback_vector());
|
||||
}
|
||||
|
||||
static void GetMinInobjectSlack(Map* map, void* data) {
|
||||
|
@ -1827,7 +1827,6 @@ bool V8HeapExplorer::IsEssentialObject(Object* object) {
|
||||
object != heap_->empty_byte_array() &&
|
||||
object != heap_->empty_fixed_array() &&
|
||||
object != heap_->empty_descriptor_array() &&
|
||||
object != heap_->empty_feedback_vector() &&
|
||||
object != heap_->fixed_array_map() && object != heap_->cell_map() &&
|
||||
object != heap_->global_property_cell_map() &&
|
||||
object != heap_->shared_function_info_map() &&
|
||||
|
@ -117,6 +117,7 @@ class InterpreterTester {
|
||||
function->shared()->set_function_data(*bytecode_.ToHandleChecked());
|
||||
}
|
||||
if (!feedback_metadata_.is_null()) {
|
||||
function->set_feedback_vector_cell(isolate_->heap()->undefined_cell());
|
||||
function->shared()->set_feedback_metadata(
|
||||
*feedback_metadata_.ToHandleChecked());
|
||||
JSFunction::EnsureLiterals(function);
|
||||
|
@ -38,13 +38,7 @@ TEST(VectorStructure) {
|
||||
Factory* factory = isolate->factory();
|
||||
Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
|
||||
// Empty vectors are the empty fixed array.
|
||||
StaticFeedbackVectorSpec empty;
|
||||
Handle<FeedbackVector> vector = NewFeedbackVector(isolate, &empty);
|
||||
CHECK(Handle<FixedArray>::cast(vector).is_identical_to(
|
||||
factory->empty_feedback_vector()));
|
||||
// Which can nonetheless be queried.
|
||||
CHECK(vector->is_empty());
|
||||
Handle<FeedbackVector> vector;
|
||||
|
||||
{
|
||||
FeedbackVectorSpec one_slot(&zone);
|
||||
|
@ -42,7 +42,10 @@ class FeedbackVectorHelper {
|
||||
template <typename Spec>
|
||||
Handle<FeedbackVector> NewFeedbackVector(Isolate* isolate, Spec* spec) {
|
||||
Handle<FeedbackMetadata> metadata = FeedbackMetadata::New(isolate, spec);
|
||||
return FeedbackVector::New(isolate, metadata);
|
||||
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
|
||||
isolate->factory()->empty_string(), MaybeHandle<Code>(), false);
|
||||
shared->set_feedback_metadata(*metadata);
|
||||
return FeedbackVector::New(isolate, shared);
|
||||
}
|
||||
|
||||
template <typename Spec>
|
||||
|
Loading…
Reference in New Issue
Block a user