Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 057e268f7ad0e6ec9f830b449b7963a5eda30934..89cf09b89aec4775edbf5955d082e15fa276d1f3 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -8292,26 +8292,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) { |
class ActivationsFinder : public ThreadVisitor { |
public: |
- explicit ActivationsFinder(JSFunction* function) |
- : function_(function), has_activations_(false) {} |
+ Code* code_; |
+ bool has_code_activations_; |
+ |
+ explicit ActivationsFinder(Code* code) |
+ : code_(code), |
+ has_code_activations_(false) { } |
void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
- if (has_activations_) return; |
+ JavaScriptFrameIterator it(isolate, top); |
+ VisitFrames(&it); |
+ } |
- for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
- JavaScriptFrame* frame = it.frame(); |
- if (frame->is_optimized() && frame->function() == function_) { |
- has_activations_ = true; |
- return; |
- } |
+ void VisitFrames(JavaScriptFrameIterator* it) { |
+ for (; !it->done(); it->Advance()) { |
+ JavaScriptFrame* frame = it->frame(); |
+ if (code_->contains(frame->pc())) has_code_activations_ = true; |
} |
} |
- |
- bool has_activations() { return has_activations_; } |
- |
- private: |
- JSFunction* function_; |
- bool has_activations_; |
}; |
@@ -8334,7 +8332,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { |
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
ASSERT(AllowHeapAllocation::IsAllowed()); |
- ASSERT(deoptimizer->compiled_code_kind() == Code::OPTIMIZED_FUNCTION); |
+ Handle<JSFunction> function = deoptimizer->function(); |
+ Handle<Code> optimized_code = deoptimizer->compiled_code(); |
+ |
+ ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION); |
+ ASSERT(type == deoptimizer->bailout_type()); |
// Make sure to materialize objects before causing any allocation. |
JavaScriptFrameIterator it(isolate); |
@@ -8343,10 +8345,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { |
JavaScriptFrame* frame = it.frame(); |
RUNTIME_ASSERT(frame->function()->IsJSFunction()); |
- Handle<JSFunction> function(frame->function(), isolate); |
- Handle<Code> optimized_code(function->code()); |
- RUNTIME_ASSERT((type != Deoptimizer::EAGER && |
- type != Deoptimizer::SOFT) || function->IsOptimized()); |
// Avoid doing too much work when running with --always-opt and keep |
// the optimized code around. |
@@ -8354,33 +8352,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) { |
return isolate->heap()->undefined_value(); |
} |
- // Find other optimized activations of the function or functions that |
- // share the same optimized code. |
- bool has_other_activations = false; |
- while (!it.done()) { |
- JavaScriptFrame* frame = it.frame(); |
- JSFunction* other_function = frame->function(); |
- if (frame->is_optimized() && other_function->code() == function->code()) { |
- has_other_activations = true; |
- break; |
- } |
- it.Advance(); |
- } |
- |
- if (!has_other_activations) { |
- ActivationsFinder activations_finder(*function); |
- isolate->thread_manager()->IterateArchivedThreads(&activations_finder); |
- has_other_activations = activations_finder.has_activations(); |
- } |
+ // Search for other activations of the same function and code. |
+ ActivationsFinder activations_finder(*optimized_code); |
+ activations_finder.VisitFrames(&it); |
+ isolate->thread_manager()->IterateArchivedThreads(&activations_finder); |
- if (!has_other_activations) { |
- if (FLAG_trace_deopt) { |
- PrintF("[removing optimized code for: "); |
- function->PrintName(); |
- PrintF("]\n"); |
+ if (!activations_finder.has_code_activations_) { |
+ if (function->code() == *optimized_code) { |
+ if (FLAG_trace_deopt) { |
+ PrintF("[removing optimized code for: "); |
+ function->PrintName(); |
+ PrintF("]\n"); |
+ } |
+ function->ReplaceCode(function->shared()->code()); |
} |
- function->ReplaceCode(function->shared()->code()); |
} else { |
+ // TODO(titzer): we should probably do DeoptimizeCodeList(code) |
+ // unconditionally if the code is not already marked for deoptimization. |
+ // If there is an index by shared function info, all the better. |
Deoptimizer::DeoptimizeFunction(*function); |
} |
// Evict optimized code for this function from the cache so that it doesn't |