Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: src/type-feedback-vector.cc

Issue 754303003: Flesh out vector ic state query and set mechanisms. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-info.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/type-feedback-vector.cc
diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc
index 676290c83d021fff88102a40c4d65c478fb56c31..0e78358d949df687b688bc1e9edb37883c9826f9 100644
--- a/src/type-feedback-vector.cc
+++ b/src/type-feedback-vector.cc
@@ -76,12 +76,14 @@ void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
// static
-Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
- int slot_count,
- int ic_slot_count) {
- int index_count =
+Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(
+ Isolate* isolate, const FeedbackVectorSpec& spec) {
+ const int slot_count = spec.slots();
+ const int ic_slot_count = spec.ic_slots();
+ const int index_count =
FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0;
- int length = slot_count + ic_slot_count + index_count + kReservedIndexCount;
+ const int length =
+ slot_count + ic_slot_count + index_count + kReservedIndexCount;
if (length == kReservedIndexCount) {
return Handle<TypeFeedbackVector>::cast(
isolate->factory()->empty_fixed_array());
@@ -96,10 +98,6 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
}
array->set(kWithTypesIndex, Smi::FromInt(0));
array->set(kGenericCountIndex, Smi::FromInt(0));
- // Fill the indexes with zeros.
- for (int i = 0; i < index_count; i++) {
- array->set(kReservedIndexCount + i, Smi::FromInt(0));
- }
// Ensure we can skip the write barrier
Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
@@ -107,7 +105,14 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
for (int i = kReservedIndexCount + index_count; i < length; i++) {
array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
}
- return Handle<TypeFeedbackVector>::cast(array);
+
+ Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array);
+ if (FLAG_vector_ics) {
+ for (int i = 0; i < ic_slot_count; i++) {
+ vector->SetKind(FeedbackVectorICSlot(i), spec.GetKind(i));
+ }
+ }
+ return vector;
}
@@ -121,6 +126,28 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
}
+// This logic is copied from
+// StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
+// TODO(mvstanton): with weak handling of all vector ics, this logic should
+// actually be completely eliminated and we no longer need to clear the
+// vector ICs.
+static bool ClearLogic(Heap* heap, int ic_age, Code::Kind kind,
+ InlineCacheState state) {
+ if (FLAG_cleanup_code_caches_at_gc &&
+ (kind == Code::CALL_IC || state == MEGAMORPHIC || state == GENERIC ||
+ state == POLYMORPHIC || heap->flush_monomorphic_ics() ||
+ // TODO(mvstanton): is this ic_age granular enough? it comes from
+ // the SharedFunctionInfo which may change on a different schedule
+ // than ic targets.
+ // ic_age != heap->global_ic_age() ||
+ // is_invalidated_weak_stub ||
+ heap->isolate()->serializer_enabled())) {
+ return true;
+ }
+ return false;
+}
+
+
void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) {
int slots = Slots();
Isolate* isolate = GetIsolate();
@@ -145,19 +172,33 @@ void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) {
slots = ICSlots();
if (slots == 0) return;
- // Now clear vector-based ICs. They are all CallICs.
+ // Now clear vector-based ICs.
// Try and pass the containing code (the "host").
+ Heap* heap = isolate->heap();
Code* host = shared->code();
+ // I'm not sure yet if this ic age is the correct one.
+ int ic_age = shared->ic_age();
for (int i = 0; i < slots; i++) {
FeedbackVectorICSlot slot(i);
Object* obj = Get(slot);
if (obj != uninitialized_sentinel) {
- // TODO(mvstanton): To make this code work with --vector-ics,
- // additional Nexus types must be created.
- DCHECK(!FLAG_vector_ics);
- DCHECK(GetKind(slot) == Code::CALL_IC);
- CallICNexus nexus(this, slot);
- ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus);
+ Code::Kind kind = GetKind(slot);
+ if (kind == Code::CALL_IC) {
+ CallICNexus nexus(this, slot);
+ if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
+ nexus.Clear(host);
+ }
+ } else if (kind == Code::LOAD_IC) {
+ LoadICNexus nexus(this, slot);
+ if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
+ nexus.Clear(host);
+ }
+ } else if (kind == Code::KEYED_LOAD_IC) {
+ KeyedLoadICNexus nexus(this, slot);
+ if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
+ nexus.Clear(host);
+ }
+ }
}
}
}
@@ -190,23 +231,66 @@ void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
}
+InlineCacheState LoadICNexus::StateFromFeedback() const {
+ Isolate* isolate = GetIsolate();
+ Object* feedback = GetFeedback();
+ if (feedback == *vector()->UninitializedSentinel(isolate)) {
+ return UNINITIALIZED;
+ } else if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+ return MEGAMORPHIC;
+ } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
+ return PREMONOMORPHIC;
+ } else if (feedback->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(feedback);
+ int length = array->length();
+ DCHECK(length >= 2);
+ return length == 2 ? MONOMORPHIC : POLYMORPHIC;
+ }
+
+ return UNINITIALIZED;
+}
+
+
+InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
+ Isolate* isolate = GetIsolate();
+ Object* feedback = GetFeedback();
+ if (feedback == *vector()->UninitializedSentinel(isolate)) {
+ return UNINITIALIZED;
+ } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
+ return PREMONOMORPHIC;
+ } else if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+ return MEGAMORPHIC;
+ } else if (feedback == *vector()->GenericSentinel(isolate)) {
+ return GENERIC;
+ } else if (feedback->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(feedback);
+ int length = array->length();
+ DCHECK(length >= 3);
+ return length == 3 ? MONOMORPHIC : POLYMORPHIC;
+ }
+
+ return UNINITIALIZED;
+}
+
+
InlineCacheState CallICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
- InlineCacheState state = UNINITIALIZED;
Object* feedback = GetFeedback();
if (feedback == *vector()->MegamorphicSentinel(isolate)) {
- state = GENERIC;
+ return GENERIC;
} else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
- state = MONOMORPHIC;
- } else {
- CHECK(feedback == *vector()->UninitializedSentinel(isolate));
+ return MONOMORPHIC;
}
- return state;
+ CHECK(feedback == *vector()->UninitializedSentinel(isolate));
+ return UNINITIALIZED;
}
+void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); }
+
+
void CallICNexus::ConfigureGeneric() {
SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
}
@@ -233,6 +317,79 @@ void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
}
+void KeyedLoadICNexus::ConfigureGeneric() {
+ SetFeedback(*vector()->GenericSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void KeyedLoadICNexus::ConfigureMegamorphic() {
+ SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void LoadICNexus::ConfigureMegamorphic() {
+ SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void LoadICNexus::ConfigurePremonomorphic() {
+ SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
+ SKIP_WRITE_BARRIER);
+}
+
+
+void KeyedLoadICNexus::ConfigurePremonomorphic() {
+ SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
+ SKIP_WRITE_BARRIER);
+}
+
+
+void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
+ Handle<Code> handler) {
+ Handle<FixedArray> array = EnsureArrayOfSize(2);
+ Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
+ array->set(0, *receiver_map);
+ array->set(1, *handler);
+}
+
+
+void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
+ Handle<HeapType> type,
+ Handle<Code> handler) {
+ Handle<FixedArray> array = EnsureArrayOfSize(3);
+ Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
+ if (name.is_null()) {
+ array->set(0, Smi::FromInt(0));
+ } else {
+ array->set(0, *name);
+ }
+ array->set(1, *receiver_map);
+ array->set(2, *handler);
+}
+
+
+void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types,
+ CodeHandleList* handlers) {
+ int receiver_count = types->length();
+ EnsureArrayOfSize(receiver_count * 2);
+ InstallHandlers(0, types, handlers);
+}
+
+
+void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
+ TypeHandleList* types,
+ CodeHandleList* handlers) {
+ int receiver_count = types->length();
+ Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2);
+ if (name.is_null()) {
+ array->set(0, Smi::FromInt(0));
+ } else {
+ array->set(0, *name);
+ }
+ InstallHandlers(1, types, handlers);
+}
+
+
int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
@@ -289,5 +446,56 @@ bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list,
}
return count == length;
}
+
+
+int LoadICNexus::ExtractMaps(MapHandleList* maps) const {
+ return FeedbackNexus::ExtractMaps(0, maps);
+}
+
+
+void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); }
+
+
+void KeyedLoadICNexus::Clear(Code* host) {
+ KeyedLoadIC::Clear(GetIsolate(), host, this);
+}
+
+
+int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const {
+ return FeedbackNexus::ExtractMaps(1, maps);
+}
+
+
+MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const {
+ return FeedbackNexus::FindHandlerForMap(0, map);
+}
+
+
+MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const {
+ return FeedbackNexus::FindHandlerForMap(1, map);
+}
+
+
+bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const {
+ return FeedbackNexus::FindHandlers(0, code_list, length);
+}
+
+
+bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list,
+ int length) const {
+ return FeedbackNexus::FindHandlers(1, code_list, length);
+}
+
+
+Name* KeyedLoadICNexus::FindFirstName() const {
+ Object* feedback = GetFeedback();
+ if (feedback->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(feedback);
+ DCHECK(array->length() >= 3);
+ Object* name = array->get(0);
+ if (name->IsName()) return Name::cast(name);
+ }
+ return NULL;
+}
}
} // namespace v8::internal
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698