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 |