summaryrefslogtreecommitdiff
path: root/deps/v8/src/feedback-vector.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/feedback-vector.cc')
-rw-r--r--deps/v8/src/feedback-vector.cc151
1 files changed, 98 insertions, 53 deletions
diff --git a/deps/v8/src/feedback-vector.cc b/deps/v8/src/feedback-vector.cc
index 0572b85395..c3bdd82616 100644
--- a/deps/v8/src/feedback-vector.cc
+++ b/deps/v8/src/feedback-vector.cc
@@ -234,7 +234,9 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
DCHECK_EQ(vector->shared_function_info(), *shared);
DCHECK_EQ(vector->optimized_code_cell(),
- Smi::FromEnum(OptimizationMarker::kNone));
+ Smi::FromEnum(FLAG_log_function_events
+ ? OptimizationMarker::kLogFirstExecution
+ : OptimizationMarker::kNone));
DCHECK_EQ(vector->invocation_count(), 0);
DCHECK_EQ(vector->profiler_ticks(), 0);
DCHECK_EQ(vector->deopt_count(), 0);
@@ -253,6 +255,8 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
switch (kind) {
case FeedbackSlotKind::kLoadGlobalInsideTypeof:
case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
+ case FeedbackSlotKind::kStoreGlobalSloppy:
+ case FeedbackSlotKind::kStoreGlobalStrict:
vector->set(index, isolate->heap()->empty_weak_cell(),
SKIP_WRITE_BARRIER);
break;
@@ -278,8 +282,6 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
case FeedbackSlotKind::kStoreNamedSloppy:
case FeedbackSlotKind::kStoreNamedStrict:
case FeedbackSlotKind::kStoreOwnNamed:
- case FeedbackSlotKind::kStoreGlobalSloppy:
- case FeedbackSlotKind::kStoreGlobalStrict:
case FeedbackSlotKind::kStoreKeyedSloppy:
case FeedbackSlotKind::kStoreKeyedStrict:
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
@@ -341,12 +343,18 @@ void FeedbackVector::SetOptimizedCode(Handle<FeedbackVector> vector,
vector->set_optimized_code_cell(*cell);
}
-void FeedbackVector::SetOptimizationMarker(OptimizationMarker marker) {
- set_optimized_code_cell(Smi::FromEnum(marker));
+void FeedbackVector::ClearOptimizedCode() {
+ DCHECK(has_optimized_code());
+ SetOptimizationMarker(OptimizationMarker::kNone);
}
-void FeedbackVector::ClearOptimizedCode() {
- set_optimized_code_cell(Smi::FromEnum(OptimizationMarker::kNone));
+void FeedbackVector::ClearOptimizationMarker() {
+ DCHECK(!has_optimized_code());
+ SetOptimizationMarker(OptimizationMarker::kNone);
+}
+
+void FeedbackVector::SetOptimizationMarker(OptimizationMarker marker) {
+ set_optimized_code_cell(Smi::FromEnum(marker));
}
void FeedbackVector::EvictOptimizedCodeMarkedForDeoptimization(
@@ -356,7 +364,7 @@ void FeedbackVector::EvictOptimizedCodeMarkedForDeoptimization(
WeakCell* cell = WeakCell::cast(slot);
if (cell->cleared()) {
- ClearOptimizedCode();
+ ClearOptimizationMarker();
return;
}
@@ -424,10 +432,17 @@ bool FeedbackVector::ClearSlots(Isolate* isolate) {
}
case FeedbackSlotKind::kStoreNamedSloppy:
case FeedbackSlotKind::kStoreNamedStrict:
- case FeedbackSlotKind::kStoreOwnNamed:
+ case FeedbackSlotKind::kStoreOwnNamed: {
+ StoreICNexus nexus(this, slot);
+ if (!nexus.IsCleared()) {
+ nexus.Clear();
+ feedback_updated = true;
+ }
+ break;
+ }
case FeedbackSlotKind::kStoreGlobalSloppy:
case FeedbackSlotKind::kStoreGlobalStrict: {
- StoreICNexus nexus(this, slot);
+ StoreGlobalICNexus nexus(this, slot);
if (!nexus.IsCleared()) {
nexus.Clear();
feedback_updated = true;
@@ -564,18 +579,6 @@ InlineCacheState LoadICNexus::StateFromFeedback() const {
return UNINITIALIZED;
}
-InlineCacheState LoadGlobalICNexus::StateFromFeedback() const {
- Isolate* isolate = GetIsolate();
- Object* feedback = GetFeedback();
-
- Object* extra = GetFeedbackExtra();
- if (!WeakCell::cast(feedback)->cleared() ||
- extra != *FeedbackVector::UninitializedSentinel(isolate)) {
- return MONOMORPHIC;
- }
- return UNINITIALIZED;
-}
-
InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
@@ -602,6 +605,56 @@ InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
return UNINITIALIZED;
}
+void GlobalICNexus::ConfigureUninitialized() {
+ Isolate* isolate = GetIsolate();
+ SetFeedback(isolate->heap()->empty_weak_cell(), SKIP_WRITE_BARRIER);
+ SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
+ SKIP_WRITE_BARRIER);
+}
+
+void GlobalICNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
+ Isolate* isolate = GetIsolate();
+ SetFeedback(*isolate->factory()->NewWeakCell(cell));
+ SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
+ SKIP_WRITE_BARRIER);
+}
+
+bool GlobalICNexus::ConfigureLexicalVarMode(int script_context_index,
+ int context_slot_index) {
+ DCHECK_LE(0, script_context_index);
+ DCHECK_LE(0, context_slot_index);
+ if (!ContextIndexBits::is_valid(script_context_index) ||
+ !SlotIndexBits::is_valid(context_slot_index)) {
+ return false;
+ }
+ int config = ContextIndexBits::encode(script_context_index) |
+ SlotIndexBits::encode(context_slot_index);
+
+ SetFeedback(Smi::FromInt(config));
+ Isolate* isolate = GetIsolate();
+ SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
+ SKIP_WRITE_BARRIER);
+ return true;
+}
+
+void GlobalICNexus::ConfigureHandlerMode(Handle<Object> handler) {
+ SetFeedback(GetIsolate()->heap()->empty_weak_cell());
+ SetFeedbackExtra(*handler);
+}
+
+InlineCacheState GlobalICNexus::StateFromFeedback() const {
+ Isolate* isolate = GetIsolate();
+ Object* feedback = GetFeedback();
+ if (feedback->IsSmi()) return MONOMORPHIC;
+
+ Object* extra = GetFeedbackExtra();
+ if (!WeakCell::cast(feedback)->cleared() ||
+ extra != *FeedbackVector::UninitializedSentinel(isolate)) {
+ return MONOMORPHIC;
+ }
+ return UNINITIALIZED;
+}
+
InlineCacheState StoreICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
Object* feedback = GetFeedback();
@@ -667,16 +720,31 @@ InlineCacheState CallICNexus::StateFromFeedback() const {
return UNINITIALIZED;
}
-int CallICNexus::ExtractCallCount() {
+int CallICNexus::GetCallCount() {
Object* call_count = GetFeedbackExtra();
CHECK(call_count->IsSmi());
- int value = Smi::ToInt(call_count);
- return value;
+ uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
+ return CallCountField::decode(value);
}
+void CallICNexus::SetSpeculationMode(SpeculationMode mode) {
+ Object* call_count = GetFeedbackExtra();
+ CHECK(call_count->IsSmi());
+ uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
+ int result = static_cast<int>(CallCountField::decode(value) |
+ SpeculationModeField::encode(mode));
+ SetFeedbackExtra(Smi::FromInt(result), SKIP_WRITE_BARRIER);
+}
+
+SpeculationMode CallICNexus::GetSpeculationMode() {
+ Object* call_count = GetFeedbackExtra();
+ CHECK(call_count->IsSmi());
+ uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
+ return SpeculationModeField::decode(value);
+}
float CallICNexus::ComputeCallFrequency() {
double const invocation_count = vector()->invocation_count();
- double const call_count = ExtractCallCount();
+ double const call_count = GetCallCount();
if (invocation_count == 0) {
// Prevent division by 0.
return 0.0f;
@@ -691,25 +759,6 @@ void CallICNexus::ConfigureUninitialized() {
SetFeedbackExtra(Smi::kZero, SKIP_WRITE_BARRIER);
}
-void LoadGlobalICNexus::ConfigureUninitialized() {
- Isolate* isolate = GetIsolate();
- SetFeedback(isolate->heap()->empty_weak_cell(), SKIP_WRITE_BARRIER);
- SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
- SKIP_WRITE_BARRIER);
-}
-
-void LoadGlobalICNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
- Isolate* isolate = GetIsolate();
- SetFeedback(*isolate->factory()->NewWeakCell(cell));
- SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
- SKIP_WRITE_BARRIER);
-}
-
-void LoadGlobalICNexus::ConfigureHandlerMode(Handle<Object> handler) {
- SetFeedback(GetIsolate()->heap()->empty_weak_cell());
- SetFeedbackExtra(*handler);
-}
-
void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map,
Handle<Object> handler) {
@@ -896,14 +945,10 @@ KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
for (const Handle<Object>& maybe_code_handler : handlers) {
// The first handler that isn't the slow handler will have the bits we need.
Handle<Code> handler;
- if (maybe_code_handler->IsTuple3()) {
- // Elements transition.
- Handle<Tuple3> data_handler = Handle<Tuple3>::cast(maybe_code_handler);
- handler = handle(Code::cast(data_handler->value2()));
- } else if (maybe_code_handler->IsTuple2()) {
- // Element store with prototype chain check.
- Handle<Tuple2> data_handler = Handle<Tuple2>::cast(maybe_code_handler);
- handler = handle(Code::cast(data_handler->value2()));
+ if (maybe_code_handler->IsStoreHandler()) {
+ Handle<StoreHandler> data_handler =
+ Handle<StoreHandler>::cast(maybe_code_handler);
+ handler = handle(Code::cast(data_handler->smi_handler()));
} else if (maybe_code_handler->IsSmi()) {
// Skip proxy handlers.
DCHECK_EQ(*maybe_code_handler, *StoreHandler::StoreProxy(GetIsolate()));