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:
yangguo 2017-02-08 00:33:33 -08:00 committed by Commit bot
parent 6516074960
commit c78d7fa1ae
16 changed files with 34 additions and 69 deletions

View File

@ -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) \

View File

@ -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);

View File

@ -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();

View File

@ -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 {

View File

@ -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();

View File

@ -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);

View File

@ -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));

View File

@ -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) \

View File

@ -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() &&

View File

@ -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);

View File

@ -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() {

View File

@ -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) {

View File

@ -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() &&

View File

@ -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);

View File

@ -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);

View File

@ -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>