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

Side by Side Diff: src/compiler.cc

Issue 655002: Merge revisions 3777-3813 from bleding_edge to partial snapshots ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 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/data-flow.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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 25 matching lines...) Expand all
36 #include "full-codegen.h" 36 #include "full-codegen.h"
37 #include "oprofile-agent.h" 37 #include "oprofile-agent.h"
38 #include "rewriter.h" 38 #include "rewriter.h"
39 #include "scopes.h" 39 #include "scopes.h"
40 #include "usage-analyzer.h" 40 #include "usage-analyzer.h"
41 41
42 namespace v8 { 42 namespace v8 {
43 namespace internal { 43 namespace internal {
44 44
45 45
46 static Handle<Code> MakeCode(FunctionLiteral* literal, 46 static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
47 Handle<Script> script, 47 FunctionLiteral* function = info->function();
48 Handle<Context> context, 48 ASSERT(function != NULL);
49 bool is_eval,
50 CompilationInfo* info) {
51 ASSERT(literal != NULL);
52
53 // Rewrite the AST by introducing .result assignments where needed. 49 // Rewrite the AST by introducing .result assignments where needed.
54 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) { 50 if (!Rewriter::Process(function) || !AnalyzeVariableUsage(function)) {
55 // Signal a stack overflow by returning a null handle. The stack 51 // Signal a stack overflow by returning a null handle. The stack
56 // overflow exception will be thrown by the caller. 52 // overflow exception will be thrown by the caller.
57 return Handle<Code>::null(); 53 return Handle<Code>::null();
58 } 54 }
59 55
60 { 56 {
61 // Compute top scope and allocate variables. For lazy compilation 57 // Compute top scope and allocate variables. For lazy compilation
62 // the top scope only contains the single lazily compiled function, 58 // the top scope only contains the single lazily compiled function,
63 // so this doesn't re-allocate variables repeatedly. 59 // so this doesn't re-allocate variables repeatedly.
64 HistogramTimerScope timer(&Counters::variable_allocation); 60 HistogramTimerScope timer(&Counters::variable_allocation);
65 Scope* top = literal->scope(); 61 Scope* top = info->scope();
66 while (top->outer_scope() != NULL) top = top->outer_scope(); 62 while (top->outer_scope() != NULL) top = top->outer_scope();
67 top->AllocateVariables(context); 63 top->AllocateVariables(context);
68 } 64 }
69 65
70 #ifdef DEBUG 66 #ifdef DEBUG
71 if (Bootstrapper::IsActive() ? 67 if (Bootstrapper::IsActive() ?
72 FLAG_print_builtin_scopes : 68 FLAG_print_builtin_scopes :
73 FLAG_print_scopes) { 69 FLAG_print_scopes) {
74 literal->scope()->Print(); 70 info->scope()->Print();
75 } 71 }
76 #endif 72 #endif
77 73
78 // Optimize the AST. 74 // Optimize the AST.
79 if (!Rewriter::Optimize(literal)) { 75 if (!Rewriter::Optimize(function)) {
80 // Signal a stack overflow by returning a null handle. The stack 76 // Signal a stack overflow by returning a null handle. The stack
81 // overflow exception will be thrown by the caller. 77 // overflow exception will be thrown by the caller.
82 return Handle<Code>::null(); 78 return Handle<Code>::null();
83 } 79 }
84 80
85 // Generate code and return it. Code generator selection is governed by 81 // Generate code and return it. Code generator selection is governed by
86 // which backends are enabled and whether the function is considered 82 // which backends are enabled and whether the function is considered
87 // run-once code or not: 83 // run-once code or not:
88 // 84 //
89 // --full-compiler enables the dedicated backend for code we expect to be 85 // --full-compiler enables the dedicated backend for code we expect to be
90 // run once 86 // run once
91 // --fast-compiler enables a speculative optimizing backend (for 87 // --fast-compiler enables a speculative optimizing backend (for
92 // non-run-once code) 88 // non-run-once code)
93 // 89 //
94 // The normal choice of backend can be overridden with the flags 90 // The normal choice of backend can be overridden with the flags
95 // --always-full-compiler and --always-fast-compiler, which are mutually 91 // --always-full-compiler and --always-fast-compiler, which are mutually
96 // incompatible. 92 // incompatible.
97 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler); 93 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
98 94
99 Handle<SharedFunctionInfo> shared = info->shared_info(); 95 Handle<SharedFunctionInfo> shared = info->shared_info();
100 bool is_run_once = (shared.is_null()) 96 bool is_run_once = (shared.is_null())
101 ? literal->scope()->is_global_scope() 97 ? info->scope()->is_global_scope()
102 : (shared->is_toplevel() || shared->try_full_codegen()); 98 : (shared->is_toplevel() || shared->try_full_codegen());
103 99
104 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) { 100 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
105 FullCodeGenSyntaxChecker checker; 101 FullCodeGenSyntaxChecker checker;
106 checker.Check(literal); 102 checker.Check(function);
107 if (checker.has_supported_syntax()) { 103 if (checker.has_supported_syntax()) {
108 return FullCodeGenerator::MakeCode(literal, script, is_eval); 104 return FullCodeGenerator::MakeCode(info);
109 } 105 }
110 } else if (FLAG_always_fast_compiler || 106 } else if (FLAG_always_fast_compiler ||
111 (FLAG_fast_compiler && !is_run_once)) { 107 (FLAG_fast_compiler && !is_run_once)) {
112 FastCodeGenSyntaxChecker checker; 108 FastCodeGenSyntaxChecker checker;
113 checker.Check(literal, info); 109 checker.Check(info);
114 if (checker.has_supported_syntax()) { 110 if (checker.has_supported_syntax()) {
115 return FastCodeGenerator::MakeCode(literal, script, is_eval, info); 111 return FastCodeGenerator::MakeCode(info);
116 } 112 }
117 } 113 }
118 114
119 return CodeGenerator::MakeCode(literal, script, is_eval, info); 115 return CodeGenerator::MakeCode(info);
120 } 116 }
121 117
122 118
123 static Handle<JSFunction> MakeFunction(bool is_global, 119 static Handle<JSFunction> MakeFunction(bool is_global,
124 bool is_eval, 120 bool is_eval,
125 Compiler::ValidationState validate, 121 Compiler::ValidationState validate,
126 Handle<Script> script, 122 Handle<Script> script,
127 Handle<Context> context, 123 Handle<Context> context,
128 v8::Extension* extension, 124 v8::Extension* extension,
129 ScriptDataImpl* pre_data) { 125 ScriptDataImpl* pre_data) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 169
174 // Measure how long it takes to do the compilation; only take the 170 // Measure how long it takes to do the compilation; only take the
175 // rest of the function into account to avoid overlap with the 171 // rest of the function into account to avoid overlap with the
176 // parsing statistics. 172 // parsing statistics.
177 HistogramTimer* rate = is_eval 173 HistogramTimer* rate = is_eval
178 ? &Counters::compile_eval 174 ? &Counters::compile_eval
179 : &Counters::compile; 175 : &Counters::compile;
180 HistogramTimerScope timer(rate); 176 HistogramTimerScope timer(rate);
181 177
182 // Compile the code. 178 // Compile the code.
183 CompilationInfo info(Handle<SharedFunctionInfo>::null(), 179 CompilationInfo info(lit, script, is_eval);
184 Handle<Object>::null(), // No receiver. 180 Handle<Code> code = MakeCode(context, &info);
185 0); // Not nested in a loop.
186 Handle<Code> code = MakeCode(lit, script, context, is_eval, &info);
187 181
188 // Check for stack-overflow exceptions. 182 // Check for stack-overflow exceptions.
189 if (code.is_null()) { 183 if (code.is_null()) {
190 Top::StackOverflow(); 184 Top::StackOverflow();
191 return Handle<JSFunction>::null(); 185 return Handle<JSFunction>::null();
192 } 186 }
193 187
194 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT 188 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
195 // Log the code generation for the script. Check explicit whether logging is 189 // Log the code generation for the script. Check explicit whether logging is
196 // to avoid allocating when not required. 190 // to avoid allocating when not required.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 346 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
353 347
354 // The VM is in the COMPILER state until exiting this function. 348 // The VM is in the COMPILER state until exiting this function.
355 VMState state(COMPILER); 349 VMState state(COMPILER);
356 350
357 PostponeInterruptsScope postpone; 351 PostponeInterruptsScope postpone;
358 352
359 // Compute name, source code and script data. 353 // Compute name, source code and script data.
360 Handle<SharedFunctionInfo> shared = info->shared_info(); 354 Handle<SharedFunctionInfo> shared = info->shared_info();
361 Handle<String> name(String::cast(shared->name())); 355 Handle<String> name(String::cast(shared->name()));
362 Handle<Script> script(Script::cast(shared->script()));
363 356
364 int start_position = shared->start_position(); 357 int start_position = shared->start_position();
365 int end_position = shared->end_position(); 358 int end_position = shared->end_position();
366 bool is_expression = shared->is_expression(); 359 bool is_expression = shared->is_expression();
367 Counters::total_compile_size.Increment(end_position - start_position); 360 Counters::total_compile_size.Increment(end_position - start_position);
368 361
369 // Generate the AST for the lazily compiled function. The AST may be 362 // Generate the AST for the lazily compiled function. The AST may be
370 // NULL in case of parser stack overflow. 363 // NULL in case of parser stack overflow.
371 FunctionLiteral* lit = MakeLazyAST(script, name, 364 FunctionLiteral* lit = MakeLazyAST(info->script(),
365 name,
372 start_position, 366 start_position,
373 end_position, 367 end_position,
374 is_expression); 368 is_expression);
375 369
376 // Check for parse errors. 370 // Check for parse errors.
377 if (lit == NULL) { 371 if (lit == NULL) {
378 ASSERT(Top::has_pending_exception()); 372 ASSERT(Top::has_pending_exception());
379 return false; 373 return false;
380 } 374 }
375 info->set_function(lit);
381 376
382 // Measure how long it takes to do the lazy compilation; only take 377 // Measure how long it takes to do the lazy compilation; only take
383 // the rest of the function into account to avoid overlap with the 378 // the rest of the function into account to avoid overlap with the
384 // lazy parsing statistics. 379 // lazy parsing statistics.
385 HistogramTimerScope timer(&Counters::compile_lazy); 380 HistogramTimerScope timer(&Counters::compile_lazy);
386 381
387 // Compile the code. 382 // Compile the code.
388 Handle<Code> code = MakeCode(lit, 383 Handle<Code> code = MakeCode(Handle<Context>::null(), info);
389 script,
390 Handle<Context>::null(),
391 false,
392 info);
393 384
394 // Check for stack-overflow exception. 385 // Check for stack-overflow exception.
395 if (code.is_null()) { 386 if (code.is_null()) {
396 Top::StackOverflow(); 387 Top::StackOverflow();
397 return false; 388 return false;
398 } 389 }
399 390
400 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT 391 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT
401 LogCodeCreateEvent(Logger::LAZY_COMPILE_TAG, 392 LogCodeCreateEvent(Logger::LAZY_COMPILE_TAG,
402 name, 393 name,
403 Handle<String>(shared->inferred_name()), 394 Handle<String>(shared->inferred_name()),
404 start_position, 395 start_position,
405 script, 396 info->script(),
406 code); 397 code);
407 #endif 398 #endif
408 399
409 // Update the shared function info with the compiled code. 400 // Update the shared function info with the compiled code.
410 shared->set_code(*code); 401 shared->set_code(*code);
411 402
412 // Set the expected number of properties for instances. 403 // Set the expected number of properties for instances.
413 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); 404 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
414 405
415 // Set the optimication hints after performing lazy compilation, as these are 406 // Set the optimication hints after performing lazy compilation, as these are
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 } else { 438 } else {
448 // The bodies of function literals have not yet been visited by 439 // The bodies of function literals have not yet been visited by
449 // the AST optimizer/analyzer. 440 // the AST optimizer/analyzer.
450 if (!Rewriter::Optimize(literal)) { 441 if (!Rewriter::Optimize(literal)) {
451 return Handle<JSFunction>::null(); 442 return Handle<JSFunction>::null();
452 } 443 }
453 444
454 // Generate code and return it. The way that the compilation mode 445 // Generate code and return it. The way that the compilation mode
455 // is controlled by the command-line flags is described in 446 // is controlled by the command-line flags is described in
456 // the static helper function MakeCode. 447 // the static helper function MakeCode.
457 CompilationInfo info(Handle<SharedFunctionInfo>::null(), 448 CompilationInfo info(literal, script, false);
458 Handle<Object>::null(), // No receiver.
459 0); // Not nested in a loop.
460 449
461 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler); 450 CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
462 bool is_run_once = literal->try_full_codegen(); 451 bool is_run_once = literal->try_full_codegen();
463 bool is_compiled = false; 452 bool is_compiled = false;
464 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) { 453 if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
465 FullCodeGenSyntaxChecker checker; 454 FullCodeGenSyntaxChecker checker;
466 checker.Check(literal); 455 checker.Check(literal);
467 if (checker.has_supported_syntax()) { 456 if (checker.has_supported_syntax()) {
468 code = FullCodeGenerator::MakeCode(literal, 457 code = FullCodeGenerator::MakeCode(&info);
469 script,
470 false); // Not eval.
471 is_compiled = true; 458 is_compiled = true;
472 } 459 }
473 } else if (FLAG_always_fast_compiler || 460 } else if (FLAG_always_fast_compiler ||
474 (FLAG_fast_compiler && !is_run_once)) { 461 (FLAG_fast_compiler && !is_run_once)) {
475 // Since we are not lazily compiling we do not have a receiver to 462 // Since we are not lazily compiling we do not have a receiver to
476 // specialize for. 463 // specialize for.
477 FastCodeGenSyntaxChecker checker; 464 FastCodeGenSyntaxChecker checker;
478 checker.Check(literal, &info); 465 checker.Check(&info);
479 if (checker.has_supported_syntax()) { 466 if (checker.has_supported_syntax()) {
480 code = FastCodeGenerator::MakeCode(literal, script, false, &info); 467 code = FastCodeGenerator::MakeCode(&info);
481 is_compiled = true; 468 is_compiled = true;
482 } 469 }
483 } 470 }
484 471
485 if (!is_compiled) { 472 if (!is_compiled) {
486 // We fall back to the classic V8 code generator. 473 // We fall back to the classic V8 code generator.
487 code = CodeGenerator::MakeCode(literal, 474 code = CodeGenerator::MakeCode(&info);
488 script,
489 false, // Not eval.
490 &info);
491 } 475 }
492 476
493 // Check for stack-overflow exception. 477 // Check for stack-overflow exception.
494 if (code.is_null()) { 478 if (code.is_null()) {
495 caller->SetStackOverflow(); 479 caller->SetStackOverflow();
496 return Handle<JSFunction>::null(); 480 return Handle<JSFunction>::null();
497 } 481 }
498 482
499 // Function compilation complete. 483 // Function compilation complete.
500 484
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 LOG(CodeCreateEvent(tag, *code, *func_name)); 561 LOG(CodeCreateEvent(tag, *code, *func_name));
578 OProfileAgent::CreateNativeCodeRegion(*func_name, 562 OProfileAgent::CreateNativeCodeRegion(*func_name,
579 code->instruction_start(), 563 code->instruction_start(),
580 code->instruction_size()); 564 code->instruction_size());
581 } 565 }
582 } 566 }
583 } 567 }
584 #endif 568 #endif
585 569
586 } } // namespace v8::internal 570 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/data-flow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698