OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), | 87 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), |
88 script_(Handle<Script>(Script::cast(shared_info_->script()))), | 88 script_(Handle<Script>(Script::cast(shared_info_->script()))), |
89 extension_(NULL), | 89 extension_(NULL), |
90 pre_parse_data_(NULL), | 90 pre_parse_data_(NULL), |
91 supports_deoptimization_(false), | 91 supports_deoptimization_(false), |
92 osr_ast_id_(AstNode::kNoNumber) { | 92 osr_ast_id_(AstNode::kNoNumber) { |
93 Initialize(BASE); | 93 Initialize(BASE); |
94 } | 94 } |
95 | 95 |
96 | 96 |
| 97 // Disable optimization for the rest of the compilation pipeline. |
97 void CompilationInfo::DisableOptimization() { | 98 void CompilationInfo::DisableOptimization() { |
98 bool is_optimizable_closure = | 99 bool is_optimizable_closure = |
99 FLAG_optimize_closures && | 100 FLAG_optimize_closures && |
100 closure_.is_null() && | 101 closure_.is_null() && |
101 !scope_->HasTrivialOuterContext() && | 102 !scope_->HasTrivialOuterContext() && |
102 !scope_->outer_scope_calls_non_strict_eval() && | 103 !scope_->outer_scope_calls_non_strict_eval() && |
103 !scope_->inside_with(); | 104 !scope_->inside_with(); |
104 SetMode(is_optimizable_closure ? BASE : NONOPT); | 105 SetMode(is_optimizable_closure ? BASE : NONOPT); |
105 } | 106 } |
106 | 107 |
107 | 108 |
| 109 void CompilationInfo::AbortOptimization() { |
| 110 Handle<Code> code(shared_info()->code()); |
| 111 SetCode(code); |
| 112 Isolate* isolate = code->GetIsolate(); |
| 113 isolate->compilation_cache()->MarkForLazyOptimizing(closure()); |
| 114 } |
| 115 |
| 116 |
108 // Determine whether to use the full compiler for all code. If the flag | 117 // Determine whether to use the full compiler for all code. If the flag |
109 // --always-full-compiler is specified this is the case. For the virtual frame | 118 // --always-full-compiler is specified this is the case. For the virtual frame |
110 // based compiler the full compiler is also used if a debugger is connected, as | 119 // based compiler the full compiler is also used if a debugger is connected, as |
111 // the code from the full compiler supports mode precise break points. For the | 120 // the code from the full compiler supports mode precise break points. For the |
112 // crankshaft adaptive compiler debugging the optimized code is not possible at | 121 // crankshaft adaptive compiler debugging the optimized code is not possible at |
113 // all. However crankshaft support recompilation of functions, so in this case | 122 // all. However crankshaft support recompilation of functions, so in this case |
114 // the full compiler need not be be used if a debugger is attached, but only if | 123 // the full compiler need not be be used if a debugger is attached, but only if |
115 // break points has actually been set. | 124 // break points has actually been set. |
116 static bool is_debugging_active() { | 125 static bool is_debugging_active() { |
117 #ifdef ENABLE_DEBUGGER_SUPPORT | 126 #ifdef ENABLE_DEBUGGER_SUPPORT |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 compiled_functions++; | 158 compiled_functions++; |
150 code_size += function->shared()->SourceSize(); | 159 code_size += function->shared()->SourceSize(); |
151 PrintF("Compiled: %d functions with %d byte source size in %fms.\n", | 160 PrintF("Compiled: %d functions with %d byte source size in %fms.\n", |
152 compiled_functions, | 161 compiled_functions, |
153 code_size, | 162 code_size, |
154 compilation_time); | 163 compilation_time); |
155 } | 164 } |
156 } | 165 } |
157 | 166 |
158 | 167 |
159 static void AbortAndDisable(CompilationInfo* info) { | |
160 // Disable optimization for the shared function info and mark the | |
161 // code as non-optimizable. The marker on the shared function info | |
162 // is there because we flush non-optimized code thereby loosing the | |
163 // non-optimizable information for the code. When the code is | |
164 // regenerated and set on the shared function info it is marked as | |
165 // non-optimizable if optimization is disabled for the shared | |
166 // function info. | |
167 Handle<SharedFunctionInfo> shared = info->shared_info(); | |
168 shared->set_optimization_disabled(true); | |
169 Handle<Code> code = Handle<Code>(shared->code()); | |
170 ASSERT(code->kind() == Code::FUNCTION); | |
171 code->set_optimizable(false); | |
172 info->SetCode(code); | |
173 Isolate* isolate = code->GetIsolate(); | |
174 isolate->compilation_cache()->MarkForLazyOptimizing(info->closure()); | |
175 if (FLAG_trace_opt) { | |
176 PrintF("[disabled optimization for: "); | |
177 info->closure()->PrintName(); | |
178 PrintF(" / %" V8PRIxPTR "]\n", | |
179 reinterpret_cast<intptr_t>(*info->closure())); | |
180 } | |
181 } | |
182 | |
183 | |
184 static bool MakeCrankshaftCode(CompilationInfo* info) { | 168 static bool MakeCrankshaftCode(CompilationInfo* info) { |
185 // Test if we can optimize this function when asked to. We can only | 169 // Test if we can optimize this function when asked to. We can only |
186 // do this after the scopes are computed. | 170 // do this after the scopes are computed. |
187 if (!info->AllowOptimize()) info->DisableOptimization(); | 171 if (!info->AllowOptimize()) info->DisableOptimization(); |
188 | 172 |
189 // In case we are not optimizing simply return the code from | 173 // In case we are not optimizing simply return the code from |
190 // the full code generator. | 174 // the full code generator. |
191 if (!info->IsOptimizing()) { | 175 if (!info->IsOptimizing()) { |
192 return FullCodeGenerator::MakeCode(info); | 176 return FullCodeGenerator::MakeCode(info); |
193 } | 177 } |
(...skipping 13 matching lines...) Expand all Loading... |
207 if (AlwaysFullCompiler() || !FLAG_use_hydrogen) { | 191 if (AlwaysFullCompiler() || !FLAG_use_hydrogen) { |
208 info->SetCode(code); | 192 info->SetCode(code); |
209 return true; | 193 return true; |
210 } | 194 } |
211 | 195 |
212 // Limit the number of times we re-compile a functions with | 196 // Limit the number of times we re-compile a functions with |
213 // the optimizing compiler. | 197 // the optimizing compiler. |
214 const int kMaxOptCount = | 198 const int kMaxOptCount = |
215 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; | 199 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; |
216 if (info->shared_info()->opt_count() > kMaxOptCount) { | 200 if (info->shared_info()->opt_count() > kMaxOptCount) { |
217 AbortAndDisable(info); | 201 info->AbortOptimization(); |
| 202 Handle<JSFunction> closure = info->closure(); |
| 203 info->shared_info()->DisableOptimization(*closure); |
218 // True indicates the compilation pipeline is still going, not | 204 // True indicates the compilation pipeline is still going, not |
219 // necessarily that we optimized the code. | 205 // necessarily that we optimized the code. |
220 return true; | 206 return true; |
221 } | 207 } |
222 | 208 |
223 // Due to an encoding limit on LUnallocated operands in the Lithium | 209 // Due to an encoding limit on LUnallocated operands in the Lithium |
224 // language, we cannot optimize functions with too many formal parameters | 210 // language, we cannot optimize functions with too many formal parameters |
225 // or perform on-stack replacement for function with too many | 211 // or perform on-stack replacement for function with too many |
226 // stack-allocated local variables. | 212 // stack-allocated local variables. |
227 // | 213 // |
228 // The encoding is as a signed value, with parameters and receiver using | 214 // The encoding is as a signed value, with parameters and receiver using |
229 // the negative indices and locals the non-negative ones. | 215 // the negative indices and locals the non-negative ones. |
230 const int limit = LUnallocated::kMaxFixedIndices / 2; | 216 const int limit = LUnallocated::kMaxFixedIndices / 2; |
231 Scope* scope = info->scope(); | 217 Scope* scope = info->scope(); |
232 if ((scope->num_parameters() + 1) > limit || | 218 if ((scope->num_parameters() + 1) > limit || |
233 scope->num_stack_slots() > limit) { | 219 scope->num_stack_slots() > limit) { |
234 AbortAndDisable(info); | 220 info->AbortOptimization(); |
| 221 Handle<JSFunction> closure = info->closure(); |
| 222 info->shared_info()->DisableOptimization(*closure); |
235 // True indicates the compilation pipeline is still going, not | 223 // True indicates the compilation pipeline is still going, not |
236 // necessarily that we optimized the code. | 224 // necessarily that we optimized the code. |
237 return true; | 225 return true; |
238 } | 226 } |
239 | 227 |
240 // Take --hydrogen-filter into account. | 228 // Take --hydrogen-filter into account. |
241 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); | 229 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); |
242 Handle<String> name = info->function()->debug_name(); | 230 Handle<String> name = info->function()->debug_name(); |
243 bool match = filter.is_empty() || name->IsEqualTo(filter); | 231 bool match = filter.is_empty() || name->IsEqualTo(filter); |
244 if (!match) { | 232 if (!match) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 | 285 |
298 if (graph != NULL && FLAG_build_lithium) { | 286 if (graph != NULL && FLAG_build_lithium) { |
299 Handle<Code> optimized_code = graph->Compile(info); | 287 Handle<Code> optimized_code = graph->Compile(info); |
300 if (!optimized_code.is_null()) { | 288 if (!optimized_code.is_null()) { |
301 info->SetCode(optimized_code); | 289 info->SetCode(optimized_code); |
302 FinishOptimization(info->closure(), start); | 290 FinishOptimization(info->closure(), start); |
303 return true; | 291 return true; |
304 } | 292 } |
305 } | 293 } |
306 | 294 |
307 // Compilation with the Hydrogen compiler failed. Keep using the | 295 // Keep using the shared code. |
308 // shared code but mark it as unoptimizable. | 296 info->AbortOptimization(); |
309 AbortAndDisable(info); | 297 if (!builder.inline_bailout()) { |
| 298 // Mark the shared code as unoptimizable unless it was an inlined |
| 299 // function that bailed out. |
| 300 Handle<JSFunction> closure = info->closure(); |
| 301 info->shared_info()->DisableOptimization(*closure); |
| 302 } |
310 // True indicates the compilation pipeline is still going, not necessarily | 303 // True indicates the compilation pipeline is still going, not necessarily |
311 // that we optimized the code. | 304 // that we optimized the code. |
312 return true; | 305 return true; |
313 } | 306 } |
314 | 307 |
315 | 308 |
316 static bool GenerateCode(CompilationInfo* info) { | 309 static bool GenerateCode(CompilationInfo* info) { |
317 return V8::UseCrankshaft() ? | 310 return V8::UseCrankshaft() ? |
318 MakeCrankshaftCode(info) : | 311 MakeCrankshaftCode(info) : |
319 FullCodeGenerator::MakeCode(info); | 312 FullCodeGenerator::MakeCode(info); |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 shared->DebugName())); | 776 shared->DebugName())); |
784 } | 777 } |
785 } | 778 } |
786 | 779 |
787 GDBJIT(AddCode(Handle<String>(shared->DebugName()), | 780 GDBJIT(AddCode(Handle<String>(shared->DebugName()), |
788 Handle<Script>(info->script()), | 781 Handle<Script>(info->script()), |
789 Handle<Code>(info->code()))); | 782 Handle<Code>(info->code()))); |
790 } | 783 } |
791 | 784 |
792 } } // namespace v8::internal | 785 } } // namespace v8::internal |
OLD | NEW |