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

Side by Side Diff: src/compiler.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 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/cpu-profiler.h » ('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 21 matching lines...) Expand all
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 "gdb-jit.h"
39 #include "hydrogen.h" 39 #include "hydrogen.h"
40 #include "lithium.h" 40 #include "lithium.h"
41 #include "liveedit.h" 41 #include "liveedit.h"
42 #include "oprofile-agent.h"
43 #include "parser.h" 42 #include "parser.h"
44 #include "rewriter.h" 43 #include "rewriter.h"
45 #include "runtime-profiler.h" 44 #include "runtime-profiler.h"
46 #include "scopeinfo.h" 45 #include "scopeinfo.h"
47 #include "scopes.h" 46 #include "scopes.h"
48 #include "vm-state-inl.h" 47 #include "vm-state-inl.h"
49 48
50 namespace v8 { 49 namespace v8 {
51 namespace internal { 50 namespace internal {
52 51
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 // True indicates the compilation pipeline is still going, not 218 // True indicates the compilation pipeline is still going, not
220 // necessarily that we optimized the code. 219 // necessarily that we optimized the code.
221 return true; 220 return true;
222 } 221 }
223 222
224 // Due to an encoding limit on LUnallocated operands in the Lithium 223 // Due to an encoding limit on LUnallocated operands in the Lithium
225 // language, we cannot optimize functions with too many formal parameters 224 // language, we cannot optimize functions with too many formal parameters
226 // or perform on-stack replacement for function with too many 225 // or perform on-stack replacement for function with too many
227 // stack-allocated local variables. 226 // stack-allocated local variables.
228 // 227 //
229 // The encoding is as a signed value, with parameters using the negative 228 // The encoding is as a signed value, with parameters and receiver using
230 // indices and locals the non-negative ones. 229 // the negative indices and locals the non-negative ones.
231 const int limit = LUnallocated::kMaxFixedIndices / 2; 230 const int limit = LUnallocated::kMaxFixedIndices / 2;
232 Scope* scope = info->scope(); 231 Scope* scope = info->scope();
233 if (scope->num_parameters() > limit || scope->num_stack_slots() > limit) { 232 if ((scope->num_parameters() + 1) > limit ||
233 scope->num_stack_slots() > limit) {
234 AbortAndDisable(info); 234 AbortAndDisable(info);
235 // True indicates the compilation pipeline is still going, not 235 // True indicates the compilation pipeline is still going, not
236 // necessarily that we optimized the code. 236 // necessarily that we optimized the code.
237 return true; 237 return true;
238 } 238 }
239 239
240 // Take --hydrogen-filter into account. 240 // Take --hydrogen-filter into account.
241 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); 241 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
242 Handle<String> name = info->function()->debug_name(); 242 Handle<String> name = info->function()->debug_name();
243 bool match = filter.is_empty() || name->IsEqualTo(filter); 243 bool match = filter.is_empty() || name->IsEqualTo(filter);
(...skipping 15 matching lines...) Expand all
259 // optimized code. 259 // optimized code.
260 unoptimized.SetFunction(info->function()); 260 unoptimized.SetFunction(info->function());
261 unoptimized.SetScope(info->scope()); 261 unoptimized.SetScope(info->scope());
262 if (should_recompile) unoptimized.EnableDeoptimizationSupport(); 262 if (should_recompile) unoptimized.EnableDeoptimizationSupport();
263 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); 263 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
264 if (should_recompile) { 264 if (should_recompile) {
265 if (!succeeded) return false; 265 if (!succeeded) return false;
266 Handle<SharedFunctionInfo> shared = info->shared_info(); 266 Handle<SharedFunctionInfo> shared = info->shared_info();
267 shared->EnableDeoptimizationSupport(*unoptimized.code()); 267 shared->EnableDeoptimizationSupport(*unoptimized.code());
268 // The existing unoptimized code was replaced with the new one. 268 // The existing unoptimized code was replaced with the new one.
269 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, 269 Compiler::RecordFunctionCompilation(
270 Handle<String>(shared->DebugName()), 270 Logger::LAZY_COMPILE_TAG, &unoptimized, shared);
271 shared->start_position(),
272 &unoptimized);
273 } 271 }
274 } 272 }
275 273
276 // Check that the unoptimized, shared code is ready for 274 // Check that the unoptimized, shared code is ready for
277 // optimizations. When using the always_opt flag we disregard the 275 // optimizations. When using the always_opt flag we disregard the
278 // optimizable marker in the code object and optimize anyway. This 276 // optimizable marker in the code object and optimize anyway. This
279 // is safe as long as the unoptimized code has deoptimization 277 // is safe as long as the unoptimized code has deoptimization
280 // support. 278 // support.
281 ASSERT(FLAG_always_opt || info->shared_info()->code()->optimizable()); 279 ASSERT(FLAG_always_opt || code->optimizable());
282 ASSERT(info->shared_info()->has_deoptimization_support()); 280 ASSERT(info->shared_info()->has_deoptimization_support());
283 281
284 if (FLAG_trace_hydrogen) { 282 if (FLAG_trace_hydrogen) {
285 PrintF("-----------------------------------------------------------\n"); 283 PrintF("-----------------------------------------------------------\n");
286 PrintF("Compiling method %s using hydrogen\n", *name->ToCString()); 284 PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
287 HTracer::Instance()->TraceCompilation(info->function()); 285 HTracer::Instance()->TraceCompilation(info->function());
288 } 286 }
289 287
290 TypeFeedbackOracle oracle( 288 TypeFeedbackOracle oracle(
291 Handle<Code>(info->shared_info()->code()), 289 code, Handle<Context>(info->closure()->context()->global_context()));
292 Handle<Context>(info->closure()->context()->global_context()));
293 HGraphBuilder builder(&oracle); 290 HGraphBuilder builder(&oracle);
294 HPhase phase(HPhase::kTotal); 291 HPhase phase(HPhase::kTotal);
295 HGraph* graph = builder.CreateGraph(info); 292 HGraph* graph = builder.CreateGraph(info);
293 if (info->isolate()->has_pending_exception()) {
294 info->SetCode(Handle<Code>::null());
295 return false;
296 }
297
296 if (graph != NULL && FLAG_build_lithium) { 298 if (graph != NULL && FLAG_build_lithium) {
297 Handle<Code> code = graph->Compile(); 299 Handle<Code> optimized_code = graph->Compile();
298 if (!code.is_null()) { 300 if (!optimized_code.is_null()) {
299 info->SetCode(code); 301 info->SetCode(optimized_code);
300 FinishOptimization(info->closure(), start); 302 FinishOptimization(info->closure(), start);
301 return true; 303 return true;
302 } 304 }
303 } 305 }
304 306
305 // Compilation with the Hydrogen compiler failed. Keep using the 307 // Compilation with the Hydrogen compiler failed. Keep using the
306 // shared code but mark it as unoptimizable. 308 // shared code but mark it as unoptimizable.
307 AbortAndDisable(info); 309 AbortAndDisable(info);
308 // True indicates the compilation pipeline is still going, not necessarily 310 // True indicates the compilation pipeline is still going, not necessarily
309 // that we optimized the code. 311 // that we optimized the code.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 HistogramTimerScope timer(rate); 412 HistogramTimerScope timer(rate);
411 413
412 // Compile the code. 414 // Compile the code.
413 FunctionLiteral* lit = info->function(); 415 FunctionLiteral* lit = info->function();
414 LiveEditFunctionTracker live_edit_tracker(isolate, lit); 416 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
415 if (!MakeCode(info)) { 417 if (!MakeCode(info)) {
416 isolate->StackOverflow(); 418 isolate->StackOverflow();
417 return Handle<SharedFunctionInfo>::null(); 419 return Handle<SharedFunctionInfo>::null();
418 } 420 }
419 421
422 // Allocate function.
420 ASSERT(!info->code().is_null()); 423 ASSERT(!info->code().is_null());
424 Handle<SharedFunctionInfo> result =
425 isolate->factory()->NewSharedFunctionInfo(
426 lit->name(),
427 lit->materialized_literal_count(),
428 info->code(),
429 SerializedScopeInfo::Create(info->scope()));
430
431 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
432 Compiler::SetFunctionInfo(result, lit, true, script);
433
421 if (script->name()->IsString()) { 434 if (script->name()->IsString()) {
422 PROFILE(CodeCreateEvent( 435 PROFILE(CodeCreateEvent(
423 info->is_eval() 436 info->is_eval()
424 ? Logger::EVAL_TAG 437 ? Logger::EVAL_TAG
425 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 438 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
426 *info->code(), 439 *info->code(),
440 *result,
427 String::cast(script->name()))); 441 String::cast(script->name())));
428 OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
429 info->code()->instruction_start(),
430 info->code()->instruction_size()));
431 GDBJIT(AddCode(Handle<String>(String::cast(script->name())), 442 GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
432 script, 443 script,
433 info->code())); 444 info->code()));
434 } else { 445 } else {
435 PROFILE(CodeCreateEvent( 446 PROFILE(CodeCreateEvent(
436 info->is_eval() 447 info->is_eval()
437 ? Logger::EVAL_TAG 448 ? Logger::EVAL_TAG
438 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 449 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
439 *info->code(), 450 *info->code(),
440 "")); 451 *result,
441 OPROFILE(CreateNativeCodeRegion(info->is_eval() ? "Eval" : "Script", 452 isolate->heap()->empty_string()));
442 info->code()->instruction_start(),
443 info->code()->instruction_size()));
444 GDBJIT(AddCode(Handle<String>(), script, info->code())); 453 GDBJIT(AddCode(Handle<String>(), script, info->code()));
445 } 454 }
446 455
447 // Allocate function.
448 Handle<SharedFunctionInfo> result =
449 FACTORY->NewSharedFunctionInfo(
450 lit->name(),
451 lit->materialized_literal_count(),
452 info->code(),
453 SerializedScopeInfo::Create(info->scope()));
454
455 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
456 Compiler::SetFunctionInfo(result, lit, true, script);
457
458 // Hint to the runtime system used when allocating space for initial 456 // Hint to the runtime system used when allocating space for initial
459 // property space by setting the expected number of properties for 457 // property space by setting the expected number of properties for
460 // the instances of the function. 458 // the instances of the function.
461 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count()); 459 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
462 460
463 #ifdef ENABLE_DEBUGGER_SUPPORT 461 #ifdef ENABLE_DEBUGGER_SUPPORT
464 // Notify debugger 462 // Notify debugger
465 isolate->debugger()->OnAfterCompile( 463 isolate->debugger()->OnAfterCompile(
466 script, Debugger::NO_AFTER_COMPILE_FLAGS); 464 script, Debugger::NO_AFTER_COMPILE_FLAGS);
467 #endif 465 #endif
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 613
616 // Generate the AST for the lazily compiled function. 614 // Generate the AST for the lazily compiled function.
617 if (ParserApi::Parse(info)) { 615 if (ParserApi::Parse(info)) {
618 // Measure how long it takes to do the lazy compilation; only take the 616 // Measure how long it takes to do the lazy compilation; only take the
619 // rest of the function into account to avoid overlap with the lazy 617 // rest of the function into account to avoid overlap with the lazy
620 // parsing statistics. 618 // parsing statistics.
621 HistogramTimerScope timer(isolate->counters()->compile_lazy()); 619 HistogramTimerScope timer(isolate->counters()->compile_lazy());
622 620
623 // Compile the code. 621 // Compile the code.
624 if (!MakeCode(info)) { 622 if (!MakeCode(info)) {
625 isolate->StackOverflow(); 623 if (!isolate->has_pending_exception()) {
624 isolate->StackOverflow();
625 }
626 } else { 626 } else {
627 ASSERT(!info->code().is_null()); 627 ASSERT(!info->code().is_null());
628 Handle<Code> code = info->code(); 628 Handle<Code> code = info->code();
629 Handle<JSFunction> function = info->closure(); 629 Handle<JSFunction> function = info->closure();
630 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, 630 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
631 Handle<String>(shared->DebugName()),
632 shared->start_position(),
633 info);
634 631
635 if (info->IsOptimizing()) { 632 if (info->IsOptimizing()) {
636 function->ReplaceCode(*code); 633 function->ReplaceCode(*code);
637 } else { 634 } else {
638 // Update the shared function info with the compiled code and the 635 // Update the shared function info with the compiled code and the
639 // scope info. Please note, that the order of the shared function 636 // scope info. Please note, that the order of the shared function
640 // info initialization is important since set_scope_info might 637 // info initialization is important since set_scope_info might
641 // trigger a GC, causing the ASSERT below to be invalid if the code 638 // trigger a GC, causing the ASSERT below to be invalid if the code
642 // was flushed. By settting the code object last we avoid this. 639 // was flushed. By settting the code object last we avoid this.
643 Handle<SerializedScopeInfo> scope_info = 640 Handle<SerializedScopeInfo> scope_info =
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 // We fall back to the classic V8 code generator. 731 // We fall back to the classic V8 code generator.
735 if (!AssignedVariablesAnalyzer::Analyze(&info) || 732 if (!AssignedVariablesAnalyzer::Analyze(&info) ||
736 !CodeGenerator::MakeCode(&info)) { 733 !CodeGenerator::MakeCode(&info)) {
737 return Handle<SharedFunctionInfo>::null(); 734 return Handle<SharedFunctionInfo>::null();
738 } 735 }
739 } 736 }
740 } 737 }
741 ASSERT(!info.code().is_null()); 738 ASSERT(!info.code().is_null());
742 739
743 // Function compilation complete. 740 // Function compilation complete.
744 RecordFunctionCompilation(Logger::FUNCTION_TAG,
745 literal->debug_name(),
746 literal->start_position(),
747 &info);
748 scope_info = SerializedScopeInfo::Create(info.scope()); 741 scope_info = SerializedScopeInfo::Create(info.scope());
749 } 742 }
750 743
751 // Create a shared function info object. 744 // Create a shared function info object.
752 Handle<SharedFunctionInfo> result = 745 Handle<SharedFunctionInfo> result =
753 FACTORY->NewSharedFunctionInfo(literal->name(), 746 FACTORY->NewSharedFunctionInfo(literal->name(),
754 literal->materialized_literal_count(), 747 literal->materialized_literal_count(),
755 info.code(), 748 info.code(),
756 scope_info); 749 scope_info);
757 SetFunctionInfo(result, literal, false, script); 750 SetFunctionInfo(result, literal, false, script);
751 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
758 result->set_allows_lazy_compilation(allow_lazy); 752 result->set_allows_lazy_compilation(allow_lazy);
759 753
760 // Set the expected number of properties for instances and return 754 // Set the expected number of properties for instances and return
761 // the resulting function. 755 // the resulting function.
762 SetExpectedNofPropertiesFromEstimate(result, 756 SetExpectedNofPropertiesFromEstimate(result,
763 literal->expected_property_count()); 757 literal->expected_property_count());
764 live_edit_tracker.RecordFunctionInfo(result, literal); 758 live_edit_tracker.RecordFunctionInfo(result, literal);
765 return result; 759 return result;
766 } 760 }
767 761
(...skipping 18 matching lines...) Expand all
786 function_info->SetThisPropertyAssignmentsInfo( 780 function_info->SetThisPropertyAssignmentsInfo(
787 lit->has_only_simple_this_property_assignments(), 781 lit->has_only_simple_this_property_assignments(),
788 *lit->this_property_assignments()); 782 *lit->this_property_assignments());
789 function_info->set_try_full_codegen(lit->try_full_codegen()); 783 function_info->set_try_full_codegen(lit->try_full_codegen());
790 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); 784 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
791 function_info->set_strict_mode(lit->strict_mode()); 785 function_info->set_strict_mode(lit->strict_mode());
792 } 786 }
793 787
794 788
795 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, 789 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
796 Handle<String> name, 790 CompilationInfo* info,
797 int start_position, 791 Handle<SharedFunctionInfo> shared) {
798 CompilationInfo* info) { 792 // SharedFunctionInfo is passed separately, because if CompilationInfo
793 // was created using Script object, it will not have it.
794
799 // Log the code generation. If source information is available include 795 // Log the code generation. If source information is available include
800 // script name and line number. Check explicitly whether logging is 796 // script name and line number. Check explicitly whether logging is
801 // enabled as finding the line number is not free. 797 // enabled as finding the line number is not free.
802 if (info->isolate()->logger()->is_logging() || 798 if (info->isolate()->logger()->is_logging() || CpuProfiler::is_profiling()) {
803 OProfileAgent::is_enabled() ||
804 CpuProfiler::is_profiling()) {
805 Handle<Script> script = info->script(); 799 Handle<Script> script = info->script();
806 Handle<Code> code = info->code(); 800 Handle<Code> code = info->code();
801 if (*code == info->isolate()->builtins()->builtin(Builtins::LazyCompile))
802 return;
807 if (script->name()->IsString()) { 803 if (script->name()->IsString()) {
808 int line_num = GetScriptLineNumber(script, start_position) + 1; 804 int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
809 USE(line_num); 805 USE(line_num);
810 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 806 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
811 *code, 807 *code,
812 *name, 808 *shared,
813 String::cast(script->name()), 809 String::cast(script->name()),
814 line_num)); 810 line_num));
815 OPROFILE(CreateNativeCodeRegion(*name,
816 String::cast(script->name()),
817 line_num,
818 code->instruction_start(),
819 code->instruction_size()));
820 } else { 811 } else {
821 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 812 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
822 *code, 813 *code,
823 *name)); 814 *shared,
824 OPROFILE(CreateNativeCodeRegion(*name, 815 shared->DebugName()));
825 code->instruction_start(),
826 code->instruction_size()));
827 } 816 }
828 } 817 }
829 818
830 GDBJIT(AddCode(name, 819 GDBJIT(AddCode(name,
831 Handle<Script>(info->script()), 820 Handle<Script>(info->script()),
832 Handle<Code>(info->code()))); 821 Handle<Code>(info->code())));
833 } 822 }
834 823
835 } } // namespace v8::internal 824 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/cpu-profiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698