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

Unified Diff: src/deoptimizer.cc

Issue 19638014: Factor out common code from platform-specific deoptimization. Fix Deoptimizer not to need to partit… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Cleanups post-review. Created 7 years, 5 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/deoptimizer.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index fd7c2829adde7dc9ab9799385bfcb11282af0fb2..d0f5bfc9f06267ff051f7fe64c3365b27981ba9f 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -331,34 +331,47 @@ void Deoptimizer::VisitAllOptimizedFunctions(
// Removes the functions selected by the given filter from the optimized
-// function list of the given context and partitions the removed functions
-// into one or more lists such that all functions in a list share the same
-// code. The head of each list is written in the deoptimizing_functions field
-// of the corresponding code object.
-// The found code objects are returned in the given zone list.
-static void PartitionOptimizedFunctions(Context* context,
- OptimizedFunctionFilter* filter,
- ZoneList<Code*>* partitions,
- Zone* zone,
- Object* undefined) {
+// function list of the given context and adds their code to the list of
+// code objects to be deoptimized.
+static void SelectCodeToDeoptimize(Context* context,
+ OptimizedFunctionFilter* filter,
+ ZoneList<Code*>* codes,
+ Zone* zone,
+ Object* undefined) {
DisallowHeapAllocation no_allocation;
Object* current = context->get(Context::OPTIMIZED_FUNCTIONS_LIST);
Object* remainder_head = undefined;
Object* remainder_tail = undefined;
- ASSERT_EQ(0, partitions->length());
+
+ // TODO(titzer): rewrite to not modify unselected functions.
while (current != undefined) {
JSFunction* function = JSFunction::cast(current);
current = function->next_function_link();
if (filter->TakeFunction(function)) {
+ // Extract this function from the context's list and remember the code.
Code* code = function->code();
- if (code->deoptimizing_functions() == undefined) {
- partitions->Add(code, zone);
+ ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
+ if (code->marked_for_deoptimization()) {
+ ASSERT(codes->Contains(code));
} else {
- ASSERT(partitions->Contains(code));
+ code->set_marked_for_deoptimization(true);
+ codes->Add(code, zone);
+ }
+ SharedFunctionInfo* shared = function->shared();
+ // Replace the function's code with the shared code.
+ function->set_code(shared->code());
+ // Evict the code from the optimized code map.
+ shared->EvictFromOptimizedCodeMap(code, "deoptimized function");
+ // Remove the function from the optimized functions list.
+ function->set_next_function_link(undefined);
+
+ if (FLAG_trace_deopt) {
+ PrintF("[forced deoptimization: ");
+ function->PrintName();
+ PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
}
- function->set_next_function_link(code->deoptimizing_functions());
- code->set_deoptimizing_functions(function);
} else {
+ // Don't select this function; link it back into the list.
if (remainder_head == undefined) {
remainder_head = function;
} else {
@@ -393,6 +406,14 @@ class DeoptimizeWithMatchingCodeFilter : public OptimizedFunctionFilter {
};
+class DeoptimizeMarkedCodeFilter : public OptimizedFunctionFilter {
+ public:
+ virtual bool TakeFunction(JSFunction* function) {
+ return function->code()->marked_for_deoptimization();
+ }
+};
+
+
void Deoptimizer::DeoptimizeAll(Isolate* isolate) {
DisallowHeapAllocation no_allocation;
@@ -421,19 +442,11 @@ void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
- if (!function->IsOptimized()) return;
Code* code = function->code();
- Context* context = function->context()->native_context();
- Isolate* isolate = context->GetIsolate();
- Object* undefined = isolate->heap()->undefined_value();
- Zone zone(isolate);
- ZoneList<Code*> codes(1, &zone);
+ if (code->kind() != Code::OPTIMIZED_FUNCTION) return;
DeoptimizeWithMatchingCodeFilter filter(code);
- PartitionOptimizedFunctions(context, &filter, &codes, &zone, undefined);
- ASSERT_EQ(1, codes.length());
- DeoptimizeFunctionWithPreparedFunctionList(
- JSFunction::cast(codes.at(0)->deoptimizing_functions()));
- codes.at(0)->set_deoptimizing_functions(undefined);
+ DeoptimizeAllFunctionsForContext(
+ function->context()->native_context(), &filter);
}
@@ -443,12 +456,10 @@ void Deoptimizer::DeoptimizeAllFunctionsForContext(
Isolate* isolate = context->GetIsolate();
Object* undefined = isolate->heap()->undefined_value();
Zone zone(isolate);
- ZoneList<Code*> codes(1, &zone);
- PartitionOptimizedFunctions(context, filter, &codes, &zone, undefined);
- for (int i = 0; i < codes.length(); ++i) {
- DeoptimizeFunctionWithPreparedFunctionList(
- JSFunction::cast(codes.at(i)->deoptimizing_functions()));
- codes.at(i)->set_deoptimizing_functions(undefined);
+ ZoneList<Code*> codes(4, &zone);
+ SelectCodeToDeoptimize(context, filter, &codes, &zone, undefined);
+ for (int i = 0; i < codes.length(); i++) {
+ DeoptimizeCode(isolate, codes.at(i));
}
}
@@ -466,6 +477,55 @@ void Deoptimizer::DeoptimizeAllFunctionsWith(Isolate* isolate,
}
+void Deoptimizer::DeoptimizeCodeList(Isolate* isolate, ZoneList<Code*>* codes) {
+ if (codes->length() == 0) return; // Nothing to do.
+
+ // Mark the code; any functions refering to this code will be selected.
+ for (int i = 0; i < codes->length(); i++) {
+ ASSERT(!codes->at(i)->marked_for_deoptimization());
+ codes->at(i)->set_marked_for_deoptimization(true);
+ }
+
+ // For all contexts, remove optimized functions that refer to the selected
+ // code from the optimized function lists.
+ Object* undefined = isolate->heap()->undefined_value();
+ Zone zone(isolate);
+ Object* list = isolate->heap()->native_contexts_list();
+ DeoptimizeMarkedCodeFilter filter;
+ while (!list->IsUndefined()) {
+ Context* context = Context::cast(list);
+ // Note that selecting code unlinks the functions that refer to it.
+ SelectCodeToDeoptimize(context, &filter, codes, &zone, undefined);
+ list = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
+ }
+
+ // Now deoptimize all the code.
+ for (int i = 0; i < codes->length(); i++) {
+ DeoptimizeCode(isolate, codes->at(i));
+ }
+}
+
+
+void Deoptimizer::DeoptimizeCode(Isolate* isolate, Code* code) {
+ HandleScope scope(isolate);
+ DisallowHeapAllocation nha;
+
+ // Do platform-specific patching of the optimized code.
+ PatchCodeForDeoptimization(isolate, code);
+
+ // Add the deoptimizing code to the list.
+ DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
+ DeoptimizerData* data = isolate->deoptimizer_data();
+ node->set_next(data->deoptimizing_code_list_);
+ data->deoptimizing_code_list_ = node;
+
+ // We might be in the middle of incremental marking with compaction.
+ // Tell collector to treat this code object in a special way and
+ // ignore all slots that might have been recorded on it.
+ isolate->heap()->mark_compact_collector()->InvalidateCode(code);
+}
+
+
void Deoptimizer::HandleWeakDeoptimizedCode(v8::Isolate* isolate,
v8::Persistent<v8::Value>* obj,
void* parameter) {
@@ -2569,21 +2629,6 @@ void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
}
-void Deoptimizer::ReplaceCodeForRelatedFunctions(JSFunction* function,
- Code* code) {
- SharedFunctionInfo* shared = function->shared();
- Object* undefined = function->GetHeap()->undefined_value();
- Object* current = function;
-
- while (current != undefined) {
- JSFunction* func = JSFunction::cast(current);
- current = func->next_function_link();
- func->set_code(shared->code());
- func->set_next_function_link(undefined);
- }
-}
-
-
FrameDescription::FrameDescription(uint32_t frame_size,
JSFunction* function)
: frame_size_(frame_size),
« no previous file with comments | « src/deoptimizer.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698