Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: src/compiler.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler.h ('k') | src/conversions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 17 matching lines...) Expand all
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "compiler.h" 30 #include "compiler.h"
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "codegen-inl.h" 33 #include "codegen-inl.h"
34 #include "compilation-cache.h" 34 #include "compilation-cache.h"
35 #include "data-flow.h" 35 #include "data-flow.h"
36 #include "debug.h" 36 #include "debug.h"
37 #include "full-codegen.h" 37 #include "full-codegen.h"
38 #include "gdb-jit.h"
38 #include "hydrogen.h" 39 #include "hydrogen.h"
39 #include "lithium-allocator.h" 40 #include "lithium.h"
40 #include "liveedit.h" 41 #include "liveedit.h"
41 #include "oprofile-agent.h"
42 #include "parser.h" 42 #include "parser.h"
43 #include "rewriter.h" 43 #include "rewriter.h"
44 #include "runtime-profiler.h" 44 #include "runtime-profiler.h"
45 #include "scopeinfo.h" 45 #include "scopeinfo.h"
46 #include "scopes.h" 46 #include "scopes.h"
47 #include "vm-state-inl.h" 47 #include "vm-state-inl.h"
48 48
49 namespace v8 { 49 namespace v8 {
50 namespace internal { 50 namespace internal {
51 51
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 85 shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
86 script_(Handle<Script>(Script::cast(shared_info_->script()))), 86 script_(Handle<Script>(Script::cast(shared_info_->script()))),
87 extension_(NULL), 87 extension_(NULL),
88 pre_parse_data_(NULL), 88 pre_parse_data_(NULL),
89 supports_deoptimization_(false), 89 supports_deoptimization_(false),
90 osr_ast_id_(AstNode::kNoNumber) { 90 osr_ast_id_(AstNode::kNoNumber) {
91 Initialize(BASE); 91 Initialize(BASE);
92 } 92 }
93 93
94 94
95 void CompilationInfo::DisableOptimization() {
96 if (FLAG_optimize_closures) {
97 // If we allow closures optimizations and it's an optimizable closure
98 // mark it correspondingly.
99 bool is_closure = closure_.is_null() && !scope_->HasTrivialOuterContext();
100 if (is_closure) {
101 bool is_optimizable_closure =
102 !scope_->outer_scope_calls_eval() && !scope_->inside_with();
103 if (is_optimizable_closure) {
104 SetMode(BASE);
105 return;
106 }
107 }
108 }
109
110 SetMode(NONOPT);
111 }
112
113
95 // Determine whether to use the full compiler for all code. If the flag 114 // Determine whether to use the full compiler for all code. If the flag
96 // --always-full-compiler is specified this is the case. For the virtual frame 115 // --always-full-compiler is specified this is the case. For the virtual frame
97 // based compiler the full compiler is also used if a debugger is connected, as 116 // based compiler the full compiler is also used if a debugger is connected, as
98 // the code from the full compiler supports mode precise break points. For the 117 // the code from the full compiler supports mode precise break points. For the
99 // crankshaft adaptive compiler debugging the optimized code is not possible at 118 // crankshaft adaptive compiler debugging the optimized code is not possible at
100 // all. However crankshaft support recompilation of functions, so in this case 119 // all. However crankshaft support recompilation of functions, so in this case
101 // the full compiler need not be be used if a debugger is attached, but only if 120 // the full compiler need not be be used if a debugger is attached, but only if
102 // break points has actually been set. 121 // break points has actually been set.
103 static bool AlwaysFullCompiler() { 122 static bool AlwaysFullCompiler() {
104 #ifdef ENABLE_DEBUGGER_SUPPORT 123 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 // Fall back to using the full code generator if it's not possible 200 // Fall back to using the full code generator if it's not possible
182 // to use the Hydrogen-based optimizing compiler. We already have 201 // to use the Hydrogen-based optimizing compiler. We already have
183 // generated code for this from the shared function object. 202 // generated code for this from the shared function object.
184 if (AlwaysFullCompiler() || !FLAG_use_hydrogen) { 203 if (AlwaysFullCompiler() || !FLAG_use_hydrogen) {
185 info->SetCode(code); 204 info->SetCode(code);
186 return true; 205 return true;
187 } 206 }
188 207
189 // Limit the number of times we re-compile a functions with 208 // Limit the number of times we re-compile a functions with
190 // the optimizing compiler. 209 // the optimizing compiler.
191 const int kMaxOptCount = FLAG_deopt_every_n_times == 0 ? 10 : 1000; 210 const int kMaxOptCount =
211 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000;
192 if (info->shared_info()->opt_count() > kMaxOptCount) { 212 if (info->shared_info()->opt_count() > kMaxOptCount) {
193 AbortAndDisable(info); 213 AbortAndDisable(info);
194 // True indicates the compilation pipeline is still going, not 214 // True indicates the compilation pipeline is still going, not
195 // necessarily that we optimized the code. 215 // necessarily that we optimized the code.
196 return true; 216 return true;
197 } 217 }
198 218
199 // Due to an encoding limit on LUnallocated operands in the Lithium 219 // Due to an encoding limit on LUnallocated operands in the Lithium
200 // language, we cannot optimize functions with too many formal parameters 220 // language, we cannot optimize functions with too many formal parameters
201 // or perform on-stack replacement for function with too many 221 // or perform on-stack replacement for function with too many
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 // support. 275 // support.
256 ASSERT(FLAG_always_opt || info->shared_info()->code()->optimizable()); 276 ASSERT(FLAG_always_opt || info->shared_info()->code()->optimizable());
257 ASSERT(info->shared_info()->has_deoptimization_support()); 277 ASSERT(info->shared_info()->has_deoptimization_support());
258 278
259 if (FLAG_trace_hydrogen) { 279 if (FLAG_trace_hydrogen) {
260 PrintF("-----------------------------------------------------------\n"); 280 PrintF("-----------------------------------------------------------\n");
261 PrintF("Compiling method %s using hydrogen\n", *name->ToCString()); 281 PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
262 HTracer::Instance()->TraceCompilation(info->function()); 282 HTracer::Instance()->TraceCompilation(info->function());
263 } 283 }
264 284
265 TypeFeedbackOracle oracle(Handle<Code>(info->shared_info()->code())); 285 TypeFeedbackOracle oracle(
286 Handle<Code>(info->shared_info()->code()),
287 Handle<Context>(info->closure()->context()->global_context()));
266 HGraphBuilder builder(&oracle); 288 HGraphBuilder builder(&oracle);
267 HPhase phase(HPhase::kTotal); 289 HPhase phase(HPhase::kTotal);
268 HGraph* graph = builder.CreateGraph(info); 290 HGraph* graph = builder.CreateGraph(info);
291 if (Top::has_pending_exception()) {
292 info->SetCode(Handle<Code>::null());
293 return false;
294 }
295
269 if (graph != NULL && FLAG_build_lithium) { 296 if (graph != NULL && FLAG_build_lithium) {
270 Handle<Code> code = graph->Compile(); 297 Handle<Code> code = graph->Compile();
271 if (!code.is_null()) { 298 if (!code.is_null()) {
272 info->SetCode(code); 299 info->SetCode(code);
273 FinishOptimization(info->closure(), start); 300 FinishOptimization(info->closure(), start);
274 return true; 301 return true;
275 } 302 }
276 } 303 }
277 304
278 // Compilation with the Hydrogen compiler failed. Keep using the 305 // Compilation with the Hydrogen compiler failed. Keep using the
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 416 }
390 417
391 ASSERT(!info->code().is_null()); 418 ASSERT(!info->code().is_null());
392 if (script->name()->IsString()) { 419 if (script->name()->IsString()) {
393 PROFILE(CodeCreateEvent( 420 PROFILE(CodeCreateEvent(
394 info->is_eval() 421 info->is_eval()
395 ? Logger::EVAL_TAG 422 ? Logger::EVAL_TAG
396 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 423 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
397 *info->code(), 424 *info->code(),
398 String::cast(script->name()))); 425 String::cast(script->name())));
399 OPROFILE(CreateNativeCodeRegion(String::cast(script->name()), 426 GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
400 info->code()->instruction_start(), 427 script,
401 info->code()->instruction_size())); 428 info->code()));
402 } else { 429 } else {
403 PROFILE(CodeCreateEvent( 430 PROFILE(CodeCreateEvent(
404 info->is_eval() 431 info->is_eval()
405 ? Logger::EVAL_TAG 432 ? Logger::EVAL_TAG
406 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 433 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
407 *info->code(), 434 *info->code(),
408 "")); 435 ""));
409 OPROFILE(CreateNativeCodeRegion(info->is_eval() ? "Eval" : "Script", 436 GDBJIT(AddCode(Handle<String>(), script, info->code()));
410 info->code()->instruction_start(),
411 info->code()->instruction_size()));
412 } 437 }
413 438
414 // Allocate function. 439 // Allocate function.
415 Handle<SharedFunctionInfo> result = 440 Handle<SharedFunctionInfo> result =
416 Factory::NewSharedFunctionInfo( 441 Factory::NewSharedFunctionInfo(
417 lit->name(), 442 lit->name(),
418 lit->materialized_literal_count(), 443 lit->materialized_literal_count(),
419 info->code(), 444 info->code(),
420 SerializedScopeInfo::Create(info->scope())); 445 SerializedScopeInfo::Create(info->scope()));
421 446
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 } 539 }
515 } 540 }
516 541
517 if (result.is_null()) Top::ReportPendingMessages(); 542 if (result.is_null()) Top::ReportPendingMessages();
518 return result; 543 return result;
519 } 544 }
520 545
521 546
522 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, 547 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
523 Handle<Context> context, 548 Handle<Context> context,
524 bool is_global) { 549 bool is_global,
550 StrictModeFlag strict_mode) {
525 int source_length = source->length(); 551 int source_length = source->length();
526 Counters::total_eval_size.Increment(source_length); 552 Counters::total_eval_size.Increment(source_length);
527 Counters::total_compile_size.Increment(source_length); 553 Counters::total_compile_size.Increment(source_length);
528 554
529 // The VM is in the COMPILER state until exiting this function. 555 // The VM is in the COMPILER state until exiting this function.
530 VMState state(COMPILER); 556 VMState state(COMPILER);
531 557
532 // Do a lookup in the compilation cache; if the entry is not there, invoke 558 // Do a lookup in the compilation cache; if the entry is not there, invoke
533 // the compiler and add the result to the cache. 559 // the compiler and add the result to the cache.
534 Handle<SharedFunctionInfo> result; 560 Handle<SharedFunctionInfo> result;
535 result = CompilationCache::LookupEval(source, context, is_global); 561 result = CompilationCache::LookupEval(source,
562 context,
563 is_global,
564 strict_mode);
536 565
537 if (result.is_null()) { 566 if (result.is_null()) {
538 // Create a script object describing the script to be compiled. 567 // Create a script object describing the script to be compiled.
539 Handle<Script> script = Factory::NewScript(source); 568 Handle<Script> script = Factory::NewScript(source);
540 CompilationInfo info(script); 569 CompilationInfo info(script);
541 info.MarkAsEval(); 570 info.MarkAsEval();
542 if (is_global) info.MarkAsGlobal(); 571 if (is_global) info.MarkAsGlobal();
572 if (strict_mode == kStrictMode) info.MarkAsStrict();
543 info.SetCallingContext(context); 573 info.SetCallingContext(context);
544 result = MakeFunctionInfo(&info); 574 result = MakeFunctionInfo(&info);
545 if (!result.is_null()) { 575 if (!result.is_null()) {
576 // If caller is strict mode, the result must be strict as well,
577 // but not the other way around. Consider:
578 // eval("'use strict'; ...");
579 ASSERT(strict_mode == kNonStrictMode || result->strict_mode());
546 CompilationCache::PutEval(source, context, is_global, result); 580 CompilationCache::PutEval(source, context, is_global, result);
547 } 581 }
548 } 582 }
549 583
550 return result; 584 return result;
551 } 585 }
552 586
553 587
554 bool Compiler::CompileLazy(CompilationInfo* info) { 588 bool Compiler::CompileLazy(CompilationInfo* info) {
555 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 589 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
556 590
557 // The VM is in the COMPILER state until exiting this function. 591 // The VM is in the COMPILER state until exiting this function.
558 VMState state(COMPILER); 592 VMState state(COMPILER);
559 593
560 PostponeInterruptsScope postpone; 594 PostponeInterruptsScope postpone;
561 595
562 Handle<SharedFunctionInfo> shared = info->shared_info(); 596 Handle<SharedFunctionInfo> shared = info->shared_info();
563 int compiled_size = shared->end_position() - shared->start_position(); 597 int compiled_size = shared->end_position() - shared->start_position();
564 Counters::total_compile_size.Increment(compiled_size); 598 Counters::total_compile_size.Increment(compiled_size);
565 599
566 // Generate the AST for the lazily compiled function. 600 // Generate the AST for the lazily compiled function.
567 if (ParserApi::Parse(info)) { 601 if (ParserApi::Parse(info)) {
568 // Measure how long it takes to do the lazy compilation; only take the 602 // Measure how long it takes to do the lazy compilation; only take the
569 // rest of the function into account to avoid overlap with the lazy 603 // rest of the function into account to avoid overlap with the lazy
570 // parsing statistics. 604 // parsing statistics.
571 HistogramTimerScope timer(&Counters::compile_lazy); 605 HistogramTimerScope timer(&Counters::compile_lazy);
572 606
573 // Compile the code. 607 // Compile the code.
574 if (!MakeCode(info)) { 608 if (!MakeCode(info)) {
575 Top::StackOverflow(); 609 if (!Top::has_pending_exception()) {
610 Top::StackOverflow();
611 }
576 } else { 612 } else {
577 ASSERT(!info->code().is_null()); 613 ASSERT(!info->code().is_null());
578 Handle<Code> code = info->code(); 614 Handle<Code> code = info->code();
579 Handle<JSFunction> function = info->closure(); 615 Handle<JSFunction> function = info->closure();
580 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, 616 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
581 Handle<String>(shared->DebugName()), 617 Handle<String>(shared->DebugName()),
582 shared->start_position(), 618 shared->start_position(),
583 info); 619 info);
584 620
585 if (info->IsOptimizing()) { 621 if (info->IsOptimizing()) {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 function_info->set_start_position(lit->start_position()); 764 function_info->set_start_position(lit->start_position());
729 function_info->set_end_position(lit->end_position()); 765 function_info->set_end_position(lit->end_position());
730 function_info->set_is_expression(lit->is_expression()); 766 function_info->set_is_expression(lit->is_expression());
731 function_info->set_is_toplevel(is_toplevel); 767 function_info->set_is_toplevel(is_toplevel);
732 function_info->set_inferred_name(*lit->inferred_name()); 768 function_info->set_inferred_name(*lit->inferred_name());
733 function_info->SetThisPropertyAssignmentsInfo( 769 function_info->SetThisPropertyAssignmentsInfo(
734 lit->has_only_simple_this_property_assignments(), 770 lit->has_only_simple_this_property_assignments(),
735 *lit->this_property_assignments()); 771 *lit->this_property_assignments());
736 function_info->set_try_full_codegen(lit->try_full_codegen()); 772 function_info->set_try_full_codegen(lit->try_full_codegen());
737 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); 773 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
774 function_info->set_strict_mode(lit->strict_mode());
738 } 775 }
739 776
740 777
741 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, 778 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
742 Handle<String> name, 779 Handle<String> name,
743 int start_position, 780 int start_position,
744 CompilationInfo* info) { 781 CompilationInfo* info) {
745 // Log the code generation. If source information is available include 782 // Log the code generation. If source information is available include
746 // script name and line number. Check explicitly whether logging is 783 // script name and line number. Check explicitly whether logging is
747 // enabled as finding the line number is not free. 784 // enabled as finding the line number is not free.
748 if (Logger::is_logging() || 785 if (Logger::is_logging() ||
749 OProfileAgent::is_enabled() ||
750 CpuProfiler::is_profiling()) { 786 CpuProfiler::is_profiling()) {
751 Handle<Script> script = info->script(); 787 Handle<Script> script = info->script();
752 Handle<Code> code = info->code(); 788 Handle<Code> code = info->code();
753 if (script->name()->IsString()) { 789 if (script->name()->IsString()) {
754 int line_num = GetScriptLineNumber(script, start_position) + 1; 790 int line_num = GetScriptLineNumber(script, start_position) + 1;
755 USE(line_num); 791 USE(line_num);
756 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 792 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
757 *code, 793 *code,
758 *name, 794 *name,
759 String::cast(script->name()), 795 String::cast(script->name()),
760 line_num)); 796 line_num));
761 OPROFILE(CreateNativeCodeRegion(*name,
762 String::cast(script->name()),
763 line_num,
764 code->instruction_start(),
765 code->instruction_size()));
766 } else { 797 } else {
767 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 798 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
768 *code, 799 *code,
769 *name)); 800 *name));
770 OPROFILE(CreateNativeCodeRegion(*name,
771 code->instruction_start(),
772 code->instruction_size()));
773 } 801 }
774 } 802 }
803
804 GDBJIT(AddCode(name,
805 Handle<Script>(info->script()),
806 Handle<Code>(info->code())));
775 } 807 }
776 808
777 } } // namespace v8::internal 809 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/conversions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698