Index: src/debug/liveedit.cc |
diff --git a/src/debug/liveedit.cc b/src/debug/liveedit.cc |
index fe0d0c5a3976a4be6b2aa02c1f85ca07b9c3b7fc..7d33ab165991e8b8e424cd263abb202281f6fe4e 100644 |
--- a/src/debug/liveedit.cc |
+++ b/src/debug/liveedit.cc |
@@ -742,27 +742,24 @@ static void ReplaceCodeObject(Handle<Code> original, |
} |
} |
- |
-// Patch function literals. |
-// Name 'literals' is a misnomer. Rather it's a cache for complex object |
-// boilerplates and for a native context. We must clean cached values. |
-// Additionally we may need to allocate a new array if number of literals |
-// changed. |
-class LiteralFixer { |
+// Patch function feedback vector. |
+// The feedback vector is a cache for complex object boilerplates and for a |
+// native context. We must clean cached values, or if the structure of the |
+// vector itself changes we need to allocate a new one. |
+class FeedbackVectorFixer { |
public: |
- static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper, |
- Handle<SharedFunctionInfo> shared_info, |
- bool feedback_metadata_changed, Isolate* isolate) { |
+ static void PatchFeedbackVector(FunctionInfoWrapper* compile_info_wrapper, |
+ Handle<SharedFunctionInfo> shared_info, |
+ bool feedback_metadata_changed, |
+ Isolate* isolate) { |
int new_literal_count = compile_info_wrapper->GetLiteralCount(); |
- int old_literal_count = shared_info->num_literals(); |
- if (old_literal_count == new_literal_count && !feedback_metadata_changed) { |
- // If literal count didn't change, simply go over all functions |
- // and clear literal arrays. |
+ if (!feedback_metadata_changed) { |
+ // It's enough to clear the feedback vector in this case. |
ClearValuesVisitor visitor; |
IterateJSFunctions(shared_info, &visitor); |
} else { |
- // When literal count changes, we have to create new array instances. |
+ // When feedback metadata changes, we have to create new array instances. |
// Since we cannot create instances when iterating heap, we should first |
// collect all functions and fix their literal arrays. |
Handle<FixedArray> function_instances = |
@@ -774,11 +771,11 @@ class LiteralFixer { |
Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); |
Handle<TypeFeedbackVector> vector = |
TypeFeedbackVector::New(isolate, feedback_metadata); |
- fun->set_feedback_vector(*vector); |
+ fun->feedback_vector_cell()->set_value(*vector); |
} |
- |
- shared_info->set_num_literals(new_literal_count); |
} |
+ |
+ shared_info->set_num_literals(new_literal_count); |
} |
private: |
@@ -799,6 +796,18 @@ class LiteralFixer { |
} |
} |
+ template <typename Visitor> |
+ static void IterateAllJSFunctions(Heap* heap, Visitor* visitor) { |
mvstanton
2017/02/03 12:16:37
dead code, remove.
|
+ HeapIterator iterator(heap); |
+ for (HeapObject* obj = iterator.next(); obj != NULL; |
+ obj = iterator.next()) { |
+ if (obj->IsJSFunction()) { |
+ JSFunction* function = JSFunction::cast(obj); |
+ visitor->visit(function); |
+ } |
+ } |
+ } |
+ |
// Finds all instances of JSFunction that refers to the provided shared_info |
// and returns array with them. |
static Handle<FixedArray> CollectJSFunctions( |
@@ -819,8 +828,10 @@ class LiteralFixer { |
class ClearValuesVisitor { |
public: |
void visit(JSFunction* fun) { |
- TypeFeedbackVector* vector = fun->feedback_vector(); |
- vector->ClearSlots(fun->shared()); |
+ if (fun->feedback_vector_cell()->value()->IsTypeFeedbackVector()) { |
+ TypeFeedbackVector* vector = fun->feedback_vector(); |
+ vector->ClearSlots(fun->shared()); |
+ } |
} |
}; |
@@ -944,7 +955,8 @@ void LiveEdit::ReplaceFunctionCode( |
Handle<TypeFeedbackMetadata> new_feedback_metadata( |
new_shared_info->feedback_metadata()); |
feedback_metadata_changed = |
- new_feedback_metadata->DiffersFrom(shared_info->feedback_metadata()); |
+ new_feedback_metadata->DiffersFrom(shared_info->feedback_metadata()) || |
+ new_feedback_metadata->HasFunctionLiteralSlots(); |
shared_info->set_feedback_metadata(*new_feedback_metadata); |
} |
@@ -953,8 +965,8 @@ void LiveEdit::ReplaceFunctionCode( |
shared_info->set_start_position(start_position); |
shared_info->set_end_position(end_position); |
- LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, |
- feedback_metadata_changed, isolate); |
+ FeedbackVectorFixer::PatchFeedbackVector(&compile_info_wrapper, shared_info, |
+ feedback_metadata_changed, isolate); |
DeoptimizeDependentFunctions(*shared_info); |
isolate->compilation_cache()->Remove(shared_info); |