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

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

Issue 680883004: Introduce FeedbackNexus for vector-based ics. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment response. Created 6 years, 2 months 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-feedback-vector-inl.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 dcae7c72e657bacba67c4ee206fb28c57365098f..641f8b66e8f75166e1bb19ecd8097f33ca2d9ad0 100644
--- a/src/type-feedback-vector.cc
+++ b/src/type-feedback-vector.cc
@@ -4,6 +4,7 @@
#include "src/v8.h"
+#include "src/ic/ic.h"
#include "src/ic/ic-state.h"
#include "src/objects.h"
#include "src/type-feedback-vector-inl.h"
@@ -12,10 +13,69 @@ namespace v8 {
namespace internal {
// static
+TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind(
+ Code::Kind kind) {
+ if (kind == Code::CALL_IC) {
+ return KindCallIC;
+ } else if (kind == Code::LOAD_IC) {
+ return KindLoadIC;
+ } else if (kind == Code::KEYED_LOAD_IC) {
+ return KindKeyedLoadIC;
+ }
+
+ // Shouldn't get here.
+ UNREACHABLE();
+ return KindUnused;
+}
+
+
+// static
+Code::Kind TypeFeedbackVector::FromVectorICKind(VectorICKind kind) {
+ if (kind == KindCallIC)
+ return Code::CALL_IC;
+ else if (kind == KindLoadIC)
+ return Code::LOAD_IC;
+ else if (kind == KindKeyedLoadIC)
+ return Code::KEYED_LOAD_IC;
+ DCHECK(kind == KindUnused);
+ return Code::NUMBER_OF_KINDS; // Sentinel for no information.
+}
+
+
+Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
+ if (!FLAG_vector_ics) {
+ // We only have CALL_ICs
+ return Code::CALL_IC;
+ }
+
+ int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
+ int data = Smi::cast(get(index))->value();
+ VectorICKind b = VectorICComputer::decode(data, slot.ToInt());
+ return FromVectorICKind(b);
+}
+
+
+void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
+ if (!FLAG_vector_ics) {
+ // Nothing to do if we only have CALL_ICs
+ return;
+ }
+
+ VectorICKind b = FromCodeKind(kind);
+ int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
+ int data = Smi::cast(get(index))->value();
+ int new_data = VectorICComputer::encode(data, slot.ToInt(), b);
+ set(index, Smi::FromInt(new_data));
+}
+
+
+// static
Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
int slot_count,
int ic_slot_count) {
- int length = slot_count + ic_slot_count + kReservedIndexCount;
+ int index_count =
+ FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0;
+ int length = slot_count + ic_slot_count + index_count + kReservedIndexCount;
if (length == kReservedIndexCount) {
return Handle<TypeFeedbackVector>::cast(
isolate->factory()->empty_fixed_array());
@@ -24,17 +84,21 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED);
if (ic_slot_count > 0) {
array->set(kFirstICSlotIndex,
- Smi::FromInt(slot_count + kReservedIndexCount));
+ Smi::FromInt(slot_count + index_count + kReservedIndexCount));
} else {
array->set(kFirstICSlotIndex, Smi::FromInt(length));
}
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);
DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
- for (int i = kReservedIndexCount; i < length; i++) {
+ for (int i = kReservedIndexCount + index_count; i < length; i++) {
array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
}
return Handle<TypeFeedbackVector>::cast(array);
@@ -82,9 +146,142 @@ void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) {
FeedbackVectorICSlot slot(i);
Object* obj = Get(slot);
if (obj != uninitialized_sentinel) {
- ICUtility::Clear(isolate, Code::CALL_IC, host, this, slot);
+ // 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);
+ }
+ }
+}
+
+
+Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
+ Isolate* isolate = GetIsolate();
+ Handle<Object> feedback = handle(GetFeedback(), isolate);
+ if (!feedback->IsFixedArray() ||
+ FixedArray::cast(*feedback)->length() != length) {
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
+ SetFeedback(*array);
+ return array;
+ }
+ return Handle<FixedArray>::cast(feedback);
+}
+
+
+void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
+ CodeHandleList* handlers) {
+ Isolate* isolate = GetIsolate();
+ FixedArray* array = FixedArray::cast(GetFeedback());
+ int receiver_count = types->length();
+ for (int current = 0; current < receiver_count; ++current) {
+ Handle<HeapType> type = types->at(current);
+ Handle<Map> map = IC::TypeToMap(*type, isolate);
+ array->set(start_index + (current * 2), *map);
+ array->set(start_index + (current * 2 + 1), *handlers->at(current));
+ }
+}
+
+
+InlineCacheState CallICNexus::StateFromFeedback() const {
+ Isolate* isolate = GetIsolate();
+ InlineCacheState state = UNINITIALIZED;
+ Object* feedback = GetFeedback();
+
+ if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+ state = GENERIC;
+ } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
+ state = MONOMORPHIC;
+ } else {
+ CHECK(feedback == *vector()->UninitializedSentinel(isolate));
+ }
+
+ return state;
+}
+
+
+void CallICNexus::ConfigureGeneric() {
+ SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void CallICNexus::ConfigureMonomorphicArray() {
+ Object* feedback = GetFeedback();
+ if (!feedback->IsAllocationSite()) {
+ Handle<AllocationSite> new_site =
+ GetIsolate()->factory()->NewAllocationSite();
+ SetFeedback(*new_site);
+ }
+}
+
+
+void CallICNexus::ConfigureUninitialized() {
+ SetFeedback(*vector()->UninitializedSentinel(GetIsolate()),
+ SKIP_WRITE_BARRIER);
+}
+
+
+void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
+ SetFeedback(*function);
+}
+
+
+int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
+ Isolate* isolate = GetIsolate();
+ Object* feedback = GetFeedback();
+ if (feedback->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(feedback);
+ // The array should be of the form [<optional name>], then
+ // [map, handler, map, handler, ... ]
+ DCHECK(array->length() >= (2 + start_index));
+ for (int i = start_index; i < array->length(); i += 2) {
+ Map* map = Map::cast(array->get(i));
+ maps->Add(handle(map, isolate));
+ }
+ return (array->length() - start_index) / 2;
+ }
+
+ return 0;
+}
+
+
+MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index,
+ Handle<Map> map) const {
+ Object* feedback = GetFeedback();
+ if (feedback->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(feedback);
+ for (int i = start_index; i < array->length(); i += 2) {
+ Map* array_map = Map::cast(array->get(i));
+ if (array_map == *map) {
+ Code* code = Code::cast(array->get(i + 1));
+ DCHECK(code->kind() == Code::HANDLER);
+ return handle(code);
+ }
+ }
+ }
+
+ return MaybeHandle<Code>();
+}
+
+
+bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list,
+ int length) const {
+ Object* feedback = GetFeedback();
+ int count = 0;
+ if (feedback->IsFixedArray()) {
+ FixedArray* array = FixedArray::cast(feedback);
+ // The array should be of the form [<optional name>], then
+ // [map, handler, map, handler, ... ]
+ DCHECK(array->length() >= (2 + start_index));
+ for (int i = start_index; i < array->length(); i += 2) {
+ Code* code = Code::cast(array->get(i + 1));
+ DCHECK(code->kind() == Code::HANDLER);
+ code_list->Add(handle(code));
+ count++;
}
}
+ return count == length;
}
}
} // namespace v8::internal
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-feedback-vector-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698