| 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 |