| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 namespace v8 { | 53 namespace v8 { |
| 54 namespace internal { | 54 namespace internal { |
| 55 | 55 |
| 56 | 56 |
| 57 CompilationInfo::CompilationInfo(Handle<Script> script, | 57 CompilationInfo::CompilationInfo(Handle<Script> script, |
| 58 Zone* zone) | 58 Zone* zone) |
| 59 : flags_(LanguageModeField::encode(CLASSIC_MODE)), | 59 : flags_(LanguageModeField::encode(CLASSIC_MODE)), |
| 60 script_(script), | 60 script_(script), |
| 61 osr_ast_id_(BailoutId::None()), | 61 osr_ast_id_(BailoutId::None()), |
| 62 parameter_count_(0), | 62 parameter_count_(0), |
| 63 this_has_uses_(true) { | 63 this_has_uses_(true), |
| 64 optimization_id_(-1) { |
| 64 Initialize(script->GetIsolate(), BASE, zone); | 65 Initialize(script->GetIsolate(), BASE, zone); |
| 65 } | 66 } |
| 66 | 67 |
| 67 | 68 |
| 68 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, | 69 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, |
| 69 Zone* zone) | 70 Zone* zone) |
| 70 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), | 71 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), |
| 71 shared_info_(shared_info), | 72 shared_info_(shared_info), |
| 72 script_(Handle<Script>(Script::cast(shared_info->script()))), | 73 script_(Handle<Script>(Script::cast(shared_info->script()))), |
| 73 osr_ast_id_(BailoutId::None()), | 74 osr_ast_id_(BailoutId::None()), |
| 74 parameter_count_(0), | 75 parameter_count_(0), |
| 75 this_has_uses_(true) { | 76 this_has_uses_(true), |
| 77 optimization_id_(-1) { |
| 76 Initialize(script_->GetIsolate(), BASE, zone); | 78 Initialize(script_->GetIsolate(), BASE, zone); |
| 77 } | 79 } |
| 78 | 80 |
| 79 | 81 |
| 80 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, | 82 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, |
| 81 Zone* zone) | 83 Zone* zone) |
| 82 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), | 84 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), |
| 83 closure_(closure), | 85 closure_(closure), |
| 84 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), | 86 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), |
| 85 script_(Handle<Script>(Script::cast(shared_info_->script()))), | 87 script_(Handle<Script>(Script::cast(shared_info_->script()))), |
| 86 context_(closure->context()), | 88 context_(closure->context()), |
| 87 osr_ast_id_(BailoutId::None()), | 89 osr_ast_id_(BailoutId::None()), |
| 88 parameter_count_(0), | 90 parameter_count_(0), |
| 89 this_has_uses_(true) { | 91 this_has_uses_(true), |
| 92 optimization_id_(-1) { |
| 90 Initialize(script_->GetIsolate(), BASE, zone); | 93 Initialize(script_->GetIsolate(), BASE, zone); |
| 91 } | 94 } |
| 92 | 95 |
| 93 | 96 |
| 94 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, | 97 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, |
| 95 Isolate* isolate, | 98 Isolate* isolate, |
| 96 Zone* zone) | 99 Zone* zone) |
| 97 : flags_(LanguageModeField::encode(CLASSIC_MODE) | | 100 : flags_(LanguageModeField::encode(CLASSIC_MODE) | |
| 98 IsLazy::encode(true)), | 101 IsLazy::encode(true)), |
| 99 osr_ast_id_(BailoutId::None()), | 102 osr_ast_id_(BailoutId::None()), |
| 100 parameter_count_(0), | 103 parameter_count_(0), |
| 101 this_has_uses_(true) { | 104 this_has_uses_(true), |
| 105 optimization_id_(-1) { |
| 102 Initialize(isolate, STUB, zone); | 106 Initialize(isolate, STUB, zone); |
| 103 code_stub_ = stub; | 107 code_stub_ = stub; |
| 104 } | 108 } |
| 105 | 109 |
| 106 | 110 |
| 107 void CompilationInfo::Initialize(Isolate* isolate, | 111 void CompilationInfo::Initialize(Isolate* isolate, |
| 108 Mode mode, | 112 Mode mode, |
| 109 Zone* zone) { | 113 Zone* zone) { |
| 110 isolate_ = isolate; | 114 isolate_ = isolate; |
| 111 function_ = NULL; | 115 function_ = NULL; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 return scope()->num_heap_slots(); | 208 return scope()->num_heap_slots(); |
| 205 } | 209 } |
| 206 } | 210 } |
| 207 | 211 |
| 208 | 212 |
| 209 Code::Flags CompilationInfo::flags() const { | 213 Code::Flags CompilationInfo::flags() const { |
| 210 if (IsStub()) { | 214 if (IsStub()) { |
| 211 return Code::ComputeFlags(code_stub()->GetCodeKind(), | 215 return Code::ComputeFlags(code_stub()->GetCodeKind(), |
| 212 code_stub()->GetICState(), | 216 code_stub()->GetICState(), |
| 213 code_stub()->GetExtraICState(), | 217 code_stub()->GetExtraICState(), |
| 214 code_stub()->GetStubType(), | 218 code_stub()->GetStubType()); |
| 215 code_stub()->GetStubFlags()); | |
| 216 } else { | 219 } else { |
| 217 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); | 220 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); |
| 218 } | 221 } |
| 219 } | 222 } |
| 220 | 223 |
| 221 | 224 |
| 222 // Disable optimization for the rest of the compilation pipeline. | 225 // Disable optimization for the rest of the compilation pipeline. |
| 223 void CompilationInfo::DisableOptimization() { | 226 void CompilationInfo::DisableOptimization() { |
| 224 bool is_optimizable_closure = | 227 bool is_optimizable_closure = |
| 225 FLAG_optimize_closures && | 228 FLAG_optimize_closures && |
| (...skipping 10 matching lines...) Expand all Loading... |
| 236 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. | 239 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. |
| 237 bool CompilationInfo::ShouldSelfOptimize() { | 240 bool CompilationInfo::ShouldSelfOptimize() { |
| 238 return FLAG_crankshaft && | 241 return FLAG_crankshaft && |
| 239 !function()->flags()->Contains(kDontSelfOptimize) && | 242 !function()->flags()->Contains(kDontSelfOptimize) && |
| 240 !function()->dont_optimize() && | 243 !function()->dont_optimize() && |
| 241 function()->scope()->AllowsLazyCompilation() && | 244 function()->scope()->AllowsLazyCompilation() && |
| 242 (shared_info().is_null() || !shared_info()->optimization_disabled()); | 245 (shared_info().is_null() || !shared_info()->optimization_disabled()); |
| 243 } | 246 } |
| 244 | 247 |
| 245 | 248 |
| 249 void CompilationInfo::PrepareForCompilation(Scope* scope) { |
| 250 ASSERT(scope_ == NULL); |
| 251 scope_ = scope; |
| 252 function()->ProcessFeedbackSlots(isolate_); |
| 253 } |
| 254 |
| 255 |
| 246 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder { | 256 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder { |
| 247 public: | 257 public: |
| 248 explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) | 258 explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) |
| 249 : HOptimizedGraphBuilder(info) { | 259 : HOptimizedGraphBuilder(info) { |
| 250 } | 260 } |
| 251 | 261 |
| 252 #define DEF_VISIT(type) \ | 262 #define DEF_VISIT(type) \ |
| 253 virtual void Visit##type(type* node) V8_OVERRIDE { \ | 263 virtual void Visit##type(type* node) V8_OVERRIDE { \ |
| 254 if (node->position() != RelocInfo::kNoPosition) { \ | 264 if (node->position() != RelocInfo::kNoPosition) { \ |
| 255 SetSourcePosition(node->position()); \ | 265 SetSourcePosition(node->position()); \ |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 bool should_recompile = !info()->shared_info()->has_deoptimization_support(); | 366 bool should_recompile = !info()->shared_info()->has_deoptimization_support(); |
| 357 if (should_recompile || FLAG_hydrogen_stats) { | 367 if (should_recompile || FLAG_hydrogen_stats) { |
| 358 ElapsedTimer timer; | 368 ElapsedTimer timer; |
| 359 if (FLAG_hydrogen_stats) { | 369 if (FLAG_hydrogen_stats) { |
| 360 timer.Start(); | 370 timer.Start(); |
| 361 } | 371 } |
| 362 CompilationInfoWithZone unoptimized(info()->shared_info()); | 372 CompilationInfoWithZone unoptimized(info()->shared_info()); |
| 363 // Note that we use the same AST that we will use for generating the | 373 // Note that we use the same AST that we will use for generating the |
| 364 // optimized code. | 374 // optimized code. |
| 365 unoptimized.SetFunction(info()->function()); | 375 unoptimized.SetFunction(info()->function()); |
| 366 unoptimized.SetScope(info()->scope()); | 376 unoptimized.PrepareForCompilation(info()->scope()); |
| 367 unoptimized.SetContext(info()->context()); | 377 unoptimized.SetContext(info()->context()); |
| 368 if (should_recompile) unoptimized.EnableDeoptimizationSupport(); | 378 if (should_recompile) unoptimized.EnableDeoptimizationSupport(); |
| 369 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); | 379 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); |
| 370 if (should_recompile) { | 380 if (should_recompile) { |
| 371 if (!succeeded) return SetLastStatus(FAILED); | 381 if (!succeeded) return SetLastStatus(FAILED); |
| 372 Handle<SharedFunctionInfo> shared = info()->shared_info(); | 382 Handle<SharedFunctionInfo> shared = info()->shared_info(); |
| 373 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 383 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
| 374 // The existing unoptimized code was replaced with the new one. | 384 // The existing unoptimized code was replaced with the new one. |
| 375 Compiler::RecordFunctionCompilation( | 385 Compiler::RecordFunctionCompilation( |
| 376 Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | 386 Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 391 if (FLAG_trace_hydrogen) { | 401 if (FLAG_trace_hydrogen) { |
| 392 Handle<String> name = info()->function()->debug_name(); | 402 Handle<String> name = info()->function()->debug_name(); |
| 393 PrintF("-----------------------------------------------------------\n"); | 403 PrintF("-----------------------------------------------------------\n"); |
| 394 PrintF("Compiling method %s using hydrogen\n", name->ToCString().get()); | 404 PrintF("Compiling method %s using hydrogen\n", name->ToCString().get()); |
| 395 isolate()->GetHTracer()->TraceCompilation(info()); | 405 isolate()->GetHTracer()->TraceCompilation(info()); |
| 396 } | 406 } |
| 397 | 407 |
| 398 // Type-check the function. | 408 // Type-check the function. |
| 399 AstTyper::Run(info()); | 409 AstTyper::Run(info()); |
| 400 | 410 |
| 401 graph_builder_ = FLAG_emit_opt_code_positions | 411 graph_builder_ = FLAG_hydrogen_track_positions |
| 402 ? new(info()->zone()) HOptimizedGraphBuilderWithPositions(info()) | 412 ? new(info()->zone()) HOptimizedGraphBuilderWithPositions(info()) |
| 403 : new(info()->zone()) HOptimizedGraphBuilder(info()); | 413 : new(info()->zone()) HOptimizedGraphBuilder(info()); |
| 404 | 414 |
| 405 Timer t(this, &time_taken_to_create_graph_); | 415 Timer t(this, &time_taken_to_create_graph_); |
| 406 info()->set_this_has_uses(false); | 416 info()->set_this_has_uses(false); |
| 407 graph_ = graph_builder_->CreateGraph(); | 417 graph_ = graph_builder_->CreateGraph(); |
| 408 | 418 |
| 409 if (isolate()->has_pending_exception()) { | 419 if (isolate()->has_pending_exception()) { |
| 410 return SetLastStatus(FAILED); | 420 return SetLastStatus(FAILED); |
| 411 } | 421 } |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 isolate->debugger()->OnBeforeCompile(script); | 782 isolate->debugger()->OnBeforeCompile(script); |
| 773 #endif | 783 #endif |
| 774 | 784 |
| 775 ASSERT(info->is_eval() || info->is_global()); | 785 ASSERT(info->is_eval() || info->is_global()); |
| 776 | 786 |
| 777 bool parse_allow_lazy = | 787 bool parse_allow_lazy = |
| 778 (info->pre_parse_data() != NULL || | 788 (info->pre_parse_data() != NULL || |
| 779 String::cast(script->source())->length() > FLAG_min_preparse_length) && | 789 String::cast(script->source())->length() > FLAG_min_preparse_length) && |
| 780 !DebuggerWantsEagerCompilation(info); | 790 !DebuggerWantsEagerCompilation(info); |
| 781 | 791 |
| 792 if (!parse_allow_lazy && info->pre_parse_data() != NULL) { |
| 793 // We are going to parse eagerly, but we have preparse data produced by lazy |
| 794 // preparsing. We cannot use it, since it won't contain all the symbols we |
| 795 // need for eager parsing. |
| 796 info->SetPreParseData(NULL); |
| 797 } |
| 798 |
| 782 Handle<SharedFunctionInfo> result; | 799 Handle<SharedFunctionInfo> result; |
| 783 | 800 |
| 784 { VMState<COMPILER> state(info->isolate()); | 801 { VMState<COMPILER> state(info->isolate()); |
| 785 if (!Parser::Parse(info, parse_allow_lazy)) { | 802 if (!Parser::Parse(info, parse_allow_lazy)) { |
| 786 return Handle<SharedFunctionInfo>::null(); | 803 return Handle<SharedFunctionInfo>::null(); |
| 787 } | 804 } |
| 788 | 805 |
| 789 FunctionLiteral* lit = info->function(); | 806 FunctionLiteral* lit = info->function(); |
| 790 LiveEditFunctionTracker live_edit_tracker(isolate, lit); | 807 LiveEditFunctionTracker live_edit_tracker(isolate, lit); |
| 791 | 808 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 if (result.is_null()) isolate->ReportPendingMessages(); | 992 if (result.is_null()) isolate->ReportPendingMessages(); |
| 976 return result; | 993 return result; |
| 977 } | 994 } |
| 978 | 995 |
| 979 | 996 |
| 980 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, | 997 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, |
| 981 Handle<Script> script) { | 998 Handle<Script> script) { |
| 982 // Precondition: code has been parsed and scopes have been analyzed. | 999 // Precondition: code has been parsed and scopes have been analyzed. |
| 983 CompilationInfoWithZone info(script); | 1000 CompilationInfoWithZone info(script); |
| 984 info.SetFunction(literal); | 1001 info.SetFunction(literal); |
| 985 info.SetScope(literal->scope()); | 1002 info.PrepareForCompilation(literal->scope()); |
| 986 info.SetLanguageMode(literal->scope()->language_mode()); | 1003 info.SetLanguageMode(literal->scope()->language_mode()); |
| 987 | 1004 |
| 988 Isolate* isolate = info.isolate(); | 1005 Isolate* isolate = info.isolate(); |
| 989 Factory* factory = isolate->factory(); | 1006 Factory* factory = isolate->factory(); |
| 990 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1007 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
| 991 // Determine if the function can be lazily compiled. This is necessary to | 1008 // Determine if the function can be lazily compiled. This is necessary to |
| 992 // allow some of our builtin JS files to be lazily compiled. These | 1009 // allow some of our builtin JS files to be lazily compiled. These |
| 993 // builtins cannot be handled lazily by the parser, since we have to know | 1010 // builtins cannot be handled lazily by the parser, since we have to know |
| 994 // if a function uses the special natives syntax, which is something the | 1011 // if a function uses the special natives syntax, which is something the |
| 995 // parser records. | 1012 // parser records. |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 return isolate->builtins()->InOptimizationQueue(); | 1188 return isolate->builtins()->InOptimizationQueue(); |
| 1172 } | 1189 } |
| 1173 } else { | 1190 } else { |
| 1174 if (GetOptimizedCodeNow(info.get())) return info->code(); | 1191 if (GetOptimizedCodeNow(info.get())) return info->code(); |
| 1175 } | 1192 } |
| 1176 | 1193 |
| 1177 // Failed. | 1194 // Failed. |
| 1178 if (FLAG_trace_opt) { | 1195 if (FLAG_trace_opt) { |
| 1179 PrintF("[failed to optimize "); | 1196 PrintF("[failed to optimize "); |
| 1180 function->PrintName(); | 1197 function->PrintName(); |
| 1181 PrintF("]\n"); | 1198 PrintF(": %s]\n", GetBailoutReason(info->bailout_reason())); |
| 1182 } | 1199 } |
| 1183 | 1200 |
| 1184 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | 1201 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
| 1185 return Handle<Code>::null(); | 1202 return Handle<Code>::null(); |
| 1186 } | 1203 } |
| 1187 | 1204 |
| 1188 | 1205 |
| 1189 Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) { | 1206 Handle<Code> Compiler::GetConcurrentlyOptimizedCode(OptimizedCompileJob* job) { |
| 1190 // Take ownership of compilation info. Deleting compilation info | 1207 // Take ownership of compilation info. Deleting compilation info |
| 1191 // also tears down the zone and the recompile job. | 1208 // also tears down the zone and the recompile job. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 AllowHandleDereference allow_deref; | 1308 AllowHandleDereference allow_deref; |
| 1292 bool tracing_on = info()->IsStub() | 1309 bool tracing_on = info()->IsStub() |
| 1293 ? FLAG_trace_hydrogen_stubs | 1310 ? FLAG_trace_hydrogen_stubs |
| 1294 : (FLAG_trace_hydrogen && | 1311 : (FLAG_trace_hydrogen && |
| 1295 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1312 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
| 1296 return (tracing_on && | 1313 return (tracing_on && |
| 1297 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1314 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
| 1298 } | 1315 } |
| 1299 | 1316 |
| 1300 } } // namespace v8::internal | 1317 } } // namespace v8::internal |
| OLD | NEW |