| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 TableEntryGenerator generator(masm, type, count); | 138 TableEntryGenerator generator(masm, type, count); |
| 139 generator.Generate(); | 139 generator.Generate(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void Deoptimizer::VisitAllOptimizedFunctionsForContext( | 142 void Deoptimizer::VisitAllOptimizedFunctionsForContext( |
| 143 Context* context, OptimizedFunctionVisitor* visitor) { | 143 Context* context, OptimizedFunctionVisitor* visitor) { |
| 144 DisallowHeapAllocation no_allocation; | 144 DisallowHeapAllocation no_allocation; |
| 145 | 145 |
| 146 CHECK(context->IsNativeContext()); | 146 CHECK(context->IsNativeContext()); |
| 147 | 147 |
| 148 visitor->EnterContext(context); | |
| 149 | |
| 150 // Visit the list of optimized functions, removing elements that | 148 // Visit the list of optimized functions, removing elements that |
| 151 // no longer refer to optimized code. | 149 // no longer refer to optimized code. |
| 152 JSFunction* prev = NULL; | 150 JSFunction* prev = NULL; |
| 153 Object* element = context->OptimizedFunctionsListHead(); | 151 Object* element = context->OptimizedFunctionsListHead(); |
| 154 Isolate* isolate = context->GetIsolate(); | 152 Isolate* isolate = context->GetIsolate(); |
| 155 while (!element->IsUndefined(isolate)) { | 153 while (!element->IsUndefined(isolate)) { |
| 156 JSFunction* function = JSFunction::cast(element); | 154 JSFunction* function = JSFunction::cast(element); |
| 157 Object* next = function->next_function_link(); | 155 Object* next = function->next_function_link(); |
| 158 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION || | 156 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION || |
| 159 (visitor->VisitFunction(function), | 157 (visitor->VisitFunction(function), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 173 function->set_next_function_link(context->GetHeap()->undefined_value(), | 171 function->set_next_function_link(context->GetHeap()->undefined_value(), |
| 174 SKIP_WRITE_BARRIER); | 172 SKIP_WRITE_BARRIER); |
| 175 } else { | 173 } else { |
| 176 // The visitor should not alter the link directly. | 174 // The visitor should not alter the link directly. |
| 177 CHECK_EQ(function->next_function_link(), next); | 175 CHECK_EQ(function->next_function_link(), next); |
| 178 // preserve this element. | 176 // preserve this element. |
| 179 prev = function; | 177 prev = function; |
| 180 } | 178 } |
| 181 element = next; | 179 element = next; |
| 182 } | 180 } |
| 181 } |
| 183 | 182 |
| 184 visitor->LeaveContext(context); | 183 void Deoptimizer::UnlinkOptimizedCode(Code* code, Context* native_context) { |
| 184 class CodeUnlinker : public OptimizedFunctionVisitor { |
| 185 public: |
| 186 explicit CodeUnlinker(Code* code) : code_(code) {} |
| 187 |
| 188 virtual void VisitFunction(JSFunction* function) { |
| 189 if (function->code() == code_) { |
| 190 if (FLAG_trace_deopt) { |
| 191 PrintF("[removing optimized code for: "); |
| 192 function->ShortPrint(); |
| 193 PrintF("]\n"); |
| 194 } |
| 195 function->set_code(function->shared()->code()); |
| 196 } |
| 197 } |
| 198 |
| 199 private: |
| 200 Code* code_; |
| 201 }; |
| 202 CodeUnlinker unlinker(code); |
| 203 VisitAllOptimizedFunctionsForContext(native_context, &unlinker); |
| 185 } | 204 } |
| 186 | 205 |
| 187 | 206 |
| 188 void Deoptimizer::VisitAllOptimizedFunctions( | 207 void Deoptimizer::VisitAllOptimizedFunctions( |
| 189 Isolate* isolate, | 208 Isolate* isolate, |
| 190 OptimizedFunctionVisitor* visitor) { | 209 OptimizedFunctionVisitor* visitor) { |
| 191 DisallowHeapAllocation no_allocation; | 210 DisallowHeapAllocation no_allocation; |
| 192 | 211 |
| 193 // Run through the list of all native contexts. | 212 // Run through the list of all native contexts. |
| 194 Object* context = isolate->heap()->native_contexts_list(); | 213 Object* context = isolate->heap()->native_contexts_list(); |
| 195 while (!context->IsUndefined(isolate)) { | 214 while (!context->IsUndefined(isolate)) { |
| 196 VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor); | 215 VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor); |
| 197 context = Context::cast(context)->next_context_link(); | 216 context = Context::cast(context)->next_context_link(); |
| 198 } | 217 } |
| 199 } | 218 } |
| 200 | 219 |
| 201 | 220 |
| 202 // Unlink functions referring to code marked for deoptimization, then move | 221 // Unlink functions referring to code marked for deoptimization, then move |
| 203 // marked code from the optimized code list to the deoptimized code list, | 222 // marked code from the optimized code list to the deoptimized code list, |
| 204 // and patch code for lazy deopt. | 223 // and patch code for lazy deopt. |
| 205 void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) { | 224 void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) { |
| 206 DisallowHeapAllocation no_allocation; | 225 DisallowHeapAllocation no_allocation; |
| 207 | 226 |
| 208 // A "closure" that unlinks optimized code that is going to be | 227 // A "closure" that unlinks optimized code that is going to be |
| 209 // deoptimized from the functions that refer to it. | 228 // deoptimized from the functions that refer to it. |
| 210 class SelectedCodeUnlinker: public OptimizedFunctionVisitor { | 229 class SelectedCodeUnlinker: public OptimizedFunctionVisitor { |
| 211 public: | 230 public: |
| 212 virtual void EnterContext(Context* context) { } // Don't care. | |
| 213 virtual void LeaveContext(Context* context) { } // Don't care. | |
| 214 virtual void VisitFunction(JSFunction* function) { | 231 virtual void VisitFunction(JSFunction* function) { |
| 215 Code* code = function->code(); | 232 Code* code = function->code(); |
| 216 if (!code->marked_for_deoptimization()) return; | 233 if (!code->marked_for_deoptimization()) return; |
| 217 | 234 |
| 218 // Unlink this function and evict from optimized code map. | 235 // Unlink this function and evict from optimized code map. |
| 219 SharedFunctionInfo* shared = function->shared(); | 236 SharedFunctionInfo* shared = function->shared(); |
| 220 function->set_code(shared->code()); | 237 function->set_code(shared->code()); |
| 221 | 238 |
| 222 if (FLAG_trace_deopt) { | 239 if (FLAG_trace_deopt) { |
| 223 CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer()); | 240 CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer()); |
| (...skipping 4182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4406 CHECK(value_info->IsMaterializedObject()); | 4423 CHECK(value_info->IsMaterializedObject()); |
| 4407 | 4424 |
| 4408 value_info->value_ = | 4425 value_info->value_ = |
| 4409 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4426 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
| 4410 } | 4427 } |
| 4411 } | 4428 } |
| 4412 } | 4429 } |
| 4413 | 4430 |
| 4414 } // namespace internal | 4431 } // namespace internal |
| 4415 } // namespace v8 | 4432 } // namespace v8 |
| OLD | NEW |