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

Side by Side Diff: src/compiler.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
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/contexts.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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
52 52
53 CompilationInfo::CompilationInfo(Handle<Script> script) 53 CompilationInfo::CompilationInfo(Handle<Script> script)
54 : flags_(0), 54 : isolate_(script->GetIsolate()),
55 flags_(0),
55 function_(NULL), 56 function_(NULL),
56 scope_(NULL), 57 scope_(NULL),
57 script_(script), 58 script_(script),
58 extension_(NULL), 59 extension_(NULL),
59 pre_parse_data_(NULL), 60 pre_parse_data_(NULL),
60 supports_deoptimization_(false), 61 supports_deoptimization_(false),
61 osr_ast_id_(AstNode::kNoNumber) { 62 osr_ast_id_(AstNode::kNoNumber) {
62 Initialize(NONOPT); 63 Initialize(NONOPT);
63 } 64 }
64 65
65 66
66 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info) 67 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info)
67 : flags_(IsLazy::encode(true)), 68 : isolate_(shared_info->GetIsolate()),
69 flags_(IsLazy::encode(true)),
68 function_(NULL), 70 function_(NULL),
69 scope_(NULL), 71 scope_(NULL),
70 shared_info_(shared_info), 72 shared_info_(shared_info),
71 script_(Handle<Script>(Script::cast(shared_info->script()))), 73 script_(Handle<Script>(Script::cast(shared_info->script()))),
72 extension_(NULL), 74 extension_(NULL),
73 pre_parse_data_(NULL), 75 pre_parse_data_(NULL),
74 supports_deoptimization_(false), 76 supports_deoptimization_(false),
75 osr_ast_id_(AstNode::kNoNumber) { 77 osr_ast_id_(AstNode::kNoNumber) {
76 Initialize(BASE); 78 Initialize(BASE);
77 } 79 }
78 80
79 81
80 CompilationInfo::CompilationInfo(Handle<JSFunction> closure) 82 CompilationInfo::CompilationInfo(Handle<JSFunction> closure)
81 : flags_(IsLazy::encode(true)), 83 : isolate_(closure->GetIsolate()),
84 flags_(IsLazy::encode(true)),
82 function_(NULL), 85 function_(NULL),
83 scope_(NULL), 86 scope_(NULL),
84 closure_(closure), 87 closure_(closure),
85 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 88 shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
86 script_(Handle<Script>(Script::cast(shared_info_->script()))), 89 script_(Handle<Script>(Script::cast(shared_info_->script()))),
87 extension_(NULL), 90 extension_(NULL),
88 pre_parse_data_(NULL), 91 pre_parse_data_(NULL),
89 supports_deoptimization_(false), 92 supports_deoptimization_(false),
90 osr_ast_id_(AstNode::kNoNumber) { 93 osr_ast_id_(AstNode::kNoNumber) {
91 Initialize(BASE); 94 Initialize(BASE);
(...skipping 22 matching lines...) Expand all
114 // 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
115 // --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
116 // 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
117 // 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
118 // crankshaft adaptive compiler debugging the optimized code is not possible at 121 // crankshaft adaptive compiler debugging the optimized code is not possible at
119 // all. However crankshaft support recompilation of functions, so in this case 122 // all. However crankshaft support recompilation of functions, so in this case
120 // 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
121 // break points has actually been set. 124 // break points has actually been set.
122 static bool AlwaysFullCompiler() { 125 static bool AlwaysFullCompiler() {
123 #ifdef ENABLE_DEBUGGER_SUPPORT 126 #ifdef ENABLE_DEBUGGER_SUPPORT
127 Isolate* isolate = Isolate::Current();
124 if (V8::UseCrankshaft()) { 128 if (V8::UseCrankshaft()) {
125 return FLAG_always_full_compiler || Debug::has_break_points(); 129 return FLAG_always_full_compiler || isolate->debug()->has_break_points();
126 } else { 130 } else {
127 return FLAG_always_full_compiler || Debugger::IsDebuggerActive(); 131 return FLAG_always_full_compiler || isolate->debugger()->IsDebuggerActive();
128 } 132 }
129 #else 133 #else
130 return FLAG_always_full_compiler; 134 return FLAG_always_full_compiler;
131 #endif 135 #endif
132 } 136 }
133 137
134 138
135 static void FinishOptimization(Handle<JSFunction> function, int64_t start) { 139 static void FinishOptimization(Handle<JSFunction> function, int64_t start) {
136 int opt_count = function->shared()->opt_count(); 140 int opt_count = function->shared()->opt_count();
137 function->shared()->set_opt_count(opt_count + 1); 141 function->shared()->set_opt_count(opt_count + 1);
(...skipping 27 matching lines...) Expand all
165 // non-optimizable information for the code. When the code is 169 // non-optimizable information for the code. When the code is
166 // regenerated and set on the shared function info it is marked as 170 // regenerated and set on the shared function info it is marked as
167 // non-optimizable if optimization is disabled for the shared 171 // non-optimizable if optimization is disabled for the shared
168 // function info. 172 // function info.
169 Handle<SharedFunctionInfo> shared = info->shared_info(); 173 Handle<SharedFunctionInfo> shared = info->shared_info();
170 shared->set_optimization_disabled(true); 174 shared->set_optimization_disabled(true);
171 Handle<Code> code = Handle<Code>(shared->code()); 175 Handle<Code> code = Handle<Code>(shared->code());
172 ASSERT(code->kind() == Code::FUNCTION); 176 ASSERT(code->kind() == Code::FUNCTION);
173 code->set_optimizable(false); 177 code->set_optimizable(false);
174 info->SetCode(code); 178 info->SetCode(code);
175 CompilationCache::MarkForLazyOptimizing(info->closure()); 179 Isolate* isolate = code->GetIsolate();
180 isolate->compilation_cache()->MarkForLazyOptimizing(info->closure());
176 if (FLAG_trace_opt) { 181 if (FLAG_trace_opt) {
177 PrintF("[disabled optimization for: "); 182 PrintF("[disabled optimization for: ");
178 info->closure()->PrintName(); 183 info->closure()->PrintName();
179 PrintF(" / %" V8PRIxPTR "]\n", 184 PrintF(" / %" V8PRIxPTR "]\n",
180 reinterpret_cast<intptr_t>(*info->closure())); 185 reinterpret_cast<intptr_t>(*info->closure()));
181 } 186 }
182 } 187 }
183 188
184 189
185 static bool MakeCrankshaftCode(CompilationInfo* info) { 190 static bool MakeCrankshaftCode(CompilationInfo* info) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 PrintF("-----------------------------------------------------------\n"); 285 PrintF("-----------------------------------------------------------\n");
281 PrintF("Compiling method %s using hydrogen\n", *name->ToCString()); 286 PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
282 HTracer::Instance()->TraceCompilation(info->function()); 287 HTracer::Instance()->TraceCompilation(info->function());
283 } 288 }
284 289
285 Handle<Context> global_context(info->closure()->context()->global_context()); 290 Handle<Context> global_context(info->closure()->context()->global_context());
286 TypeFeedbackOracle oracle(code, global_context); 291 TypeFeedbackOracle oracle(code, global_context);
287 HGraphBuilder builder(info, &oracle); 292 HGraphBuilder builder(info, &oracle);
288 HPhase phase(HPhase::kTotal); 293 HPhase phase(HPhase::kTotal);
289 HGraph* graph = builder.CreateGraph(); 294 HGraph* graph = builder.CreateGraph();
290 if (Top::has_pending_exception()) { 295 if (info->isolate()->has_pending_exception()) {
291 info->SetCode(Handle<Code>::null()); 296 info->SetCode(Handle<Code>::null());
292 return false; 297 return false;
293 } 298 }
294 299
295 if (graph != NULL && FLAG_build_lithium) { 300 if (graph != NULL && FLAG_build_lithium) {
296 Handle<Code> optimized_code = graph->Compile(info); 301 Handle<Code> optimized_code = graph->Compile(info);
297 if (!optimized_code.is_null()) { 302 if (!optimized_code.is_null()) {
298 info->SetCode(optimized_code); 303 info->SetCode(optimized_code);
299 FinishOptimization(info->closure(), start); 304 FinishOptimization(info->closure(), start);
300 return true; 305 return true;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 info->shared_info()->set_scope_info(*scope_info); 363 info->shared_info()->set_scope_info(*scope_info);
359 } 364 }
360 return succeeded; 365 return succeeded;
361 } 366 }
362 #endif 367 #endif
363 368
364 369
365 static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) { 370 static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
366 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 371 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
367 372
368 PostponeInterruptsScope postpone; 373 Isolate* isolate = info->isolate();
374 PostponeInterruptsScope postpone(isolate);
369 375
370 ASSERT(!i::Top::global_context().is_null()); 376 ASSERT(!isolate->global_context().is_null());
371 Handle<Script> script = info->script(); 377 Handle<Script> script = info->script();
372 script->set_context_data((*i::Top::global_context())->data()); 378 script->set_context_data((*isolate->global_context())->data());
373 379
374 #ifdef ENABLE_DEBUGGER_SUPPORT 380 #ifdef ENABLE_DEBUGGER_SUPPORT
375 if (info->is_eval()) { 381 if (info->is_eval()) {
376 Script::CompilationType compilation_type = Script::COMPILATION_TYPE_EVAL; 382 Script::CompilationType compilation_type = Script::COMPILATION_TYPE_EVAL;
377 script->set_compilation_type(Smi::FromInt(compilation_type)); 383 script->set_compilation_type(Smi::FromInt(compilation_type));
378 // For eval scripts add information on the function from which eval was 384 // For eval scripts add information on the function from which eval was
379 // called. 385 // called.
380 if (info->is_eval()) { 386 if (info->is_eval()) {
381 StackTraceFrameIterator it; 387 StackTraceFrameIterator it;
382 if (!it.done()) { 388 if (!it.done()) {
383 script->set_eval_from_shared( 389 script->set_eval_from_shared(
384 JSFunction::cast(it.frame()->function())->shared()); 390 JSFunction::cast(it.frame()->function())->shared());
391 Code* code = it.frame()->LookupCode(isolate);
385 int offset = static_cast<int>( 392 int offset = static_cast<int>(
386 it.frame()->pc() - it.frame()->code()->instruction_start()); 393 it.frame()->pc() - code->instruction_start());
387 script->set_eval_from_instructions_offset(Smi::FromInt(offset)); 394 script->set_eval_from_instructions_offset(Smi::FromInt(offset));
388 } 395 }
389 } 396 }
390 } 397 }
391 398
392 // Notify debugger 399 // Notify debugger
393 Debugger::OnBeforeCompile(script); 400 isolate->debugger()->OnBeforeCompile(script);
394 #endif 401 #endif
395 402
396 // Only allow non-global compiles for eval. 403 // Only allow non-global compiles for eval.
397 ASSERT(info->is_eval() || info->is_global()); 404 ASSERT(info->is_eval() || info->is_global());
398 405
399 if (!ParserApi::Parse(info)) return Handle<SharedFunctionInfo>::null(); 406 if (!ParserApi::Parse(info)) return Handle<SharedFunctionInfo>::null();
400 407
401 // Measure how long it takes to do the compilation; only take the 408 // Measure how long it takes to do the compilation; only take the
402 // rest of the function into account to avoid overlap with the 409 // rest of the function into account to avoid overlap with the
403 // parsing statistics. 410 // parsing statistics.
404 HistogramTimer* rate = info->is_eval() 411 HistogramTimer* rate = info->is_eval()
405 ? &Counters::compile_eval 412 ? COUNTERS->compile_eval()
406 : &Counters::compile; 413 : COUNTERS->compile();
407 HistogramTimerScope timer(rate); 414 HistogramTimerScope timer(rate);
408 415
409 // Compile the code. 416 // Compile the code.
410 FunctionLiteral* lit = info->function(); 417 FunctionLiteral* lit = info->function();
411 LiveEditFunctionTracker live_edit_tracker(lit); 418 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
412 if (!MakeCode(info)) { 419 if (!MakeCode(info)) {
413 Top::StackOverflow(); 420 isolate->StackOverflow();
414 return Handle<SharedFunctionInfo>::null(); 421 return Handle<SharedFunctionInfo>::null();
415 } 422 }
416 423
417 // Allocate function. 424 // Allocate function.
418 ASSERT(!info->code().is_null()); 425 ASSERT(!info->code().is_null());
419 Handle<SharedFunctionInfo> result = 426 Handle<SharedFunctionInfo> result =
420 Factory::NewSharedFunctionInfo( 427 isolate->factory()->NewSharedFunctionInfo(
421 lit->name(), 428 lit->name(),
422 lit->materialized_literal_count(), 429 lit->materialized_literal_count(),
423 info->code(), 430 info->code(),
424 SerializedScopeInfo::Create(info->scope())); 431 SerializedScopeInfo::Create(info->scope()));
425 432
426 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position()); 433 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
427 Compiler::SetFunctionInfo(result, lit, true, script); 434 Compiler::SetFunctionInfo(result, lit, true, script);
428 435
429 if (script->name()->IsString()) { 436 if (script->name()->IsString()) {
430 PROFILE(CodeCreateEvent( 437 PROFILE(isolate, CodeCreateEvent(
431 info->is_eval() 438 info->is_eval()
432 ? Logger::EVAL_TAG 439 ? Logger::EVAL_TAG
433 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 440 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
434 *info->code(), 441 *info->code(),
435 *result, 442 *result,
436 String::cast(script->name()))); 443 String::cast(script->name())));
437 GDBJIT(AddCode(Handle<String>(String::cast(script->name())), 444 GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
438 script, 445 script,
439 info->code())); 446 info->code()));
440 } else { 447 } else {
441 PROFILE(CodeCreateEvent( 448 PROFILE(isolate, CodeCreateEvent(
442 info->is_eval() 449 info->is_eval()
443 ? Logger::EVAL_TAG 450 ? Logger::EVAL_TAG
444 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 451 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
445 *info->code(), 452 *info->code(),
446 *result, 453 *result,
447 Heap::empty_string())); 454 isolate->heap()->empty_string()));
448 GDBJIT(AddCode(Handle<String>(), script, info->code())); 455 GDBJIT(AddCode(Handle<String>(), script, info->code()));
449 } 456 }
450 457
451 // Hint to the runtime system used when allocating space for initial 458 // Hint to the runtime system used when allocating space for initial
452 // property space by setting the expected number of properties for 459 // property space by setting the expected number of properties for
453 // the instances of the function. 460 // the instances of the function.
454 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count()); 461 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
455 462
456 #ifdef ENABLE_DEBUGGER_SUPPORT 463 #ifdef ENABLE_DEBUGGER_SUPPORT
457 // Notify debugger 464 // Notify debugger
458 Debugger::OnAfterCompile(script, Debugger::NO_AFTER_COMPILE_FLAGS); 465 isolate->debugger()->OnAfterCompile(
466 script, Debugger::NO_AFTER_COMPILE_FLAGS);
459 #endif 467 #endif
460 468
461 live_edit_tracker.RecordFunctionInfo(result, lit); 469 live_edit_tracker.RecordFunctionInfo(result, lit);
462 470
463 return result; 471 return result;
464 } 472 }
465 473
466 474
467 Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, 475 Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
468 Handle<Object> script_name, 476 Handle<Object> script_name,
469 int line_offset, 477 int line_offset,
470 int column_offset, 478 int column_offset,
471 v8::Extension* extension, 479 v8::Extension* extension,
472 ScriptDataImpl* input_pre_data, 480 ScriptDataImpl* input_pre_data,
473 Handle<Object> script_data, 481 Handle<Object> script_data,
474 NativesFlag natives) { 482 NativesFlag natives) {
483 Isolate* isolate = Isolate::Current();
475 int source_length = source->length(); 484 int source_length = source->length();
476 Counters::total_load_size.Increment(source_length); 485 COUNTERS->total_load_size()->Increment(source_length);
477 Counters::total_compile_size.Increment(source_length); 486 COUNTERS->total_compile_size()->Increment(source_length);
478 487
479 // The VM is in the COMPILER state until exiting this function. 488 // The VM is in the COMPILER state until exiting this function.
480 VMState state(COMPILER); 489 VMState state(isolate, COMPILER);
490
491 CompilationCache* compilation_cache = isolate->compilation_cache();
481 492
482 // Do a lookup in the compilation cache but not for extensions. 493 // Do a lookup in the compilation cache but not for extensions.
483 Handle<SharedFunctionInfo> result; 494 Handle<SharedFunctionInfo> result;
484 if (extension == NULL) { 495 if (extension == NULL) {
485 result = CompilationCache::LookupScript(source, 496 result = compilation_cache->LookupScript(source,
486 script_name, 497 script_name,
487 line_offset, 498 line_offset,
488 column_offset); 499 column_offset);
489 } 500 }
490 501
491 if (result.is_null()) { 502 if (result.is_null()) {
492 // No cache entry found. Do pre-parsing, if it makes sense, and compile 503 // No cache entry found. Do pre-parsing, if it makes sense, and compile
493 // the script. 504 // the script.
494 // Building preparse data that is only used immediately after is only a 505 // Building preparse data that is only used immediately after is only a
495 // saving if we might skip building the AST for lazily compiled functions. 506 // saving if we might skip building the AST for lazily compiled functions.
496 // I.e., preparse data isn't relevant when the lazy flag is off, and 507 // I.e., preparse data isn't relevant when the lazy flag is off, and
497 // for small sources, odds are that there aren't many functions 508 // for small sources, odds are that there aren't many functions
498 // that would be compiled lazily anyway, so we skip the preparse step 509 // that would be compiled lazily anyway, so we skip the preparse step
499 // in that case too. 510 // in that case too.
500 ScriptDataImpl* pre_data = input_pre_data; 511 ScriptDataImpl* pre_data = input_pre_data;
501 if (pre_data == NULL 512 if (pre_data == NULL
502 && source_length >= FLAG_min_preparse_length) { 513 && source_length >= FLAG_min_preparse_length) {
503 if (source->IsExternalTwoByteString()) { 514 if (source->IsExternalTwoByteString()) {
504 ExternalTwoByteStringUC16CharacterStream stream( 515 ExternalTwoByteStringUC16CharacterStream stream(
505 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 516 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
506 pre_data = ParserApi::PartialPreParse(&stream, extension); 517 pre_data = ParserApi::PartialPreParse(&stream, extension);
507 } else { 518 } else {
508 GenericStringUC16CharacterStream stream(source, 0, source->length()); 519 GenericStringUC16CharacterStream stream(source, 0, source->length());
509 pre_data = ParserApi::PartialPreParse(&stream, extension); 520 pre_data = ParserApi::PartialPreParse(&stream, extension);
510 } 521 }
511 } 522 }
512 523
513 // Create a script object describing the script to be compiled. 524 // Create a script object describing the script to be compiled.
514 Handle<Script> script = Factory::NewScript(source); 525 Handle<Script> script = FACTORY->NewScript(source);
515 if (natives == NATIVES_CODE) { 526 if (natives == NATIVES_CODE) {
516 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 527 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
517 } 528 }
518 if (!script_name.is_null()) { 529 if (!script_name.is_null()) {
519 script->set_name(*script_name); 530 script->set_name(*script_name);
520 script->set_line_offset(Smi::FromInt(line_offset)); 531 script->set_line_offset(Smi::FromInt(line_offset));
521 script->set_column_offset(Smi::FromInt(column_offset)); 532 script->set_column_offset(Smi::FromInt(column_offset));
522 } 533 }
523 534
524 script->set_data(script_data.is_null() ? Heap::undefined_value() 535 script->set_data(script_data.is_null() ? HEAP->undefined_value()
525 : *script_data); 536 : *script_data);
526 537
527 // Compile the function and add it to the cache. 538 // Compile the function and add it to the cache.
528 CompilationInfo info(script); 539 CompilationInfo info(script);
529 info.MarkAsGlobal(); 540 info.MarkAsGlobal();
530 info.SetExtension(extension); 541 info.SetExtension(extension);
531 info.SetPreParseData(pre_data); 542 info.SetPreParseData(pre_data);
532 if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax(); 543 if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax();
533 result = MakeFunctionInfo(&info); 544 result = MakeFunctionInfo(&info);
534 if (extension == NULL && !result.is_null()) { 545 if (extension == NULL && !result.is_null()) {
535 CompilationCache::PutScript(source, result); 546 compilation_cache->PutScript(source, result);
536 } 547 }
537 548
538 // Get rid of the pre-parsing data (if necessary). 549 // Get rid of the pre-parsing data (if necessary).
539 if (input_pre_data == NULL && pre_data != NULL) { 550 if (input_pre_data == NULL && pre_data != NULL) {
540 delete pre_data; 551 delete pre_data;
541 } 552 }
542 } 553 }
543 554
544 if (result.is_null()) Top::ReportPendingMessages(); 555 if (result.is_null()) isolate->ReportPendingMessages();
545 return result; 556 return result;
546 } 557 }
547 558
548 559
549 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, 560 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
550 Handle<Context> context, 561 Handle<Context> context,
551 bool is_global, 562 bool is_global,
552 StrictModeFlag strict_mode) { 563 StrictModeFlag strict_mode) {
564 Isolate* isolate = source->GetIsolate();
553 int source_length = source->length(); 565 int source_length = source->length();
554 Counters::total_eval_size.Increment(source_length); 566 isolate->counters()->total_eval_size()->Increment(source_length);
555 Counters::total_compile_size.Increment(source_length); 567 isolate->counters()->total_compile_size()->Increment(source_length);
556 568
557 // The VM is in the COMPILER state until exiting this function. 569 // The VM is in the COMPILER state until exiting this function.
558 VMState state(COMPILER); 570 VMState state(isolate, COMPILER);
559 571
560 // Do a lookup in the compilation cache; if the entry is not there, invoke 572 // Do a lookup in the compilation cache; if the entry is not there, invoke
561 // the compiler and add the result to the cache. 573 // the compiler and add the result to the cache.
562 Handle<SharedFunctionInfo> result; 574 Handle<SharedFunctionInfo> result;
563 result = CompilationCache::LookupEval(source, 575 CompilationCache* compilation_cache = isolate->compilation_cache();
564 context, 576 result = compilation_cache->LookupEval(source,
565 is_global, 577 context,
566 strict_mode); 578 is_global,
579 strict_mode);
567 580
568 if (result.is_null()) { 581 if (result.is_null()) {
569 // Create a script object describing the script to be compiled. 582 // Create a script object describing the script to be compiled.
570 Handle<Script> script = Factory::NewScript(source); 583 Handle<Script> script = isolate->factory()->NewScript(source);
571 CompilationInfo info(script); 584 CompilationInfo info(script);
572 info.MarkAsEval(); 585 info.MarkAsEval();
573 if (is_global) info.MarkAsGlobal(); 586 if (is_global) info.MarkAsGlobal();
574 if (strict_mode == kStrictMode) info.MarkAsStrict(); 587 if (strict_mode == kStrictMode) info.MarkAsStrict();
575 info.SetCallingContext(context); 588 info.SetCallingContext(context);
576 result = MakeFunctionInfo(&info); 589 result = MakeFunctionInfo(&info);
577 if (!result.is_null()) { 590 if (!result.is_null()) {
591 CompilationCache* compilation_cache = isolate->compilation_cache();
578 // If caller is strict mode, the result must be strict as well, 592 // If caller is strict mode, the result must be strict as well,
579 // but not the other way around. Consider: 593 // but not the other way around. Consider:
580 // eval("'use strict'; ..."); 594 // eval("'use strict'; ...");
581 ASSERT(strict_mode == kNonStrictMode || result->strict_mode()); 595 ASSERT(strict_mode == kNonStrictMode || result->strict_mode());
582 CompilationCache::PutEval(source, context, is_global, result); 596 compilation_cache->PutEval(source, context, is_global, result);
583 } 597 }
584 } 598 }
585 599
586 return result; 600 return result;
587 } 601 }
588 602
589 603
590 bool Compiler::CompileLazy(CompilationInfo* info) { 604 bool Compiler::CompileLazy(CompilationInfo* info) {
591 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 605 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
592 606
593 // The VM is in the COMPILER state until exiting this function. 607 // The VM is in the COMPILER state until exiting this function.
594 VMState state(COMPILER); 608 VMState state(info->isolate(), COMPILER);
595 609
596 PostponeInterruptsScope postpone; 610 Isolate* isolate = info->isolate();
611 PostponeInterruptsScope postpone(isolate);
597 612
598 Handle<SharedFunctionInfo> shared = info->shared_info(); 613 Handle<SharedFunctionInfo> shared = info->shared_info();
599 int compiled_size = shared->end_position() - shared->start_position(); 614 int compiled_size = shared->end_position() - shared->start_position();
600 Counters::total_compile_size.Increment(compiled_size); 615 isolate->counters()->total_compile_size()->Increment(compiled_size);
601 616
602 // Generate the AST for the lazily compiled function. 617 // Generate the AST for the lazily compiled function.
603 if (ParserApi::Parse(info)) { 618 if (ParserApi::Parse(info)) {
604 // Measure how long it takes to do the lazy compilation; only take the 619 // Measure how long it takes to do the lazy compilation; only take the
605 // rest of the function into account to avoid overlap with the lazy 620 // rest of the function into account to avoid overlap with the lazy
606 // parsing statistics. 621 // parsing statistics.
607 HistogramTimerScope timer(&Counters::compile_lazy); 622 HistogramTimerScope timer(isolate->counters()->compile_lazy());
608 623
609 // Compile the code. 624 // Compile the code.
610 if (!MakeCode(info)) { 625 if (!MakeCode(info)) {
611 if (!Top::has_pending_exception()) { 626 if (!isolate->has_pending_exception()) {
612 Top::StackOverflow(); 627 isolate->StackOverflow();
613 } 628 }
614 } else { 629 } else {
615 ASSERT(!info->code().is_null()); 630 ASSERT(!info->code().is_null());
616 Handle<Code> code = info->code(); 631 Handle<Code> code = info->code();
617 Handle<JSFunction> function = info->closure(); 632 Handle<JSFunction> function = info->closure();
618 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); 633 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
619 634
620 if (info->IsOptimizing()) { 635 if (info->IsOptimizing()) {
621 function->ReplaceCode(*code); 636 function->ReplaceCode(*code);
622 } else { 637 } else {
(...skipping 24 matching lines...) Expand all
647 *lit->this_property_assignments()); 662 *lit->this_property_assignments());
648 663
649 // Check the function has compiled code. 664 // Check the function has compiled code.
650 ASSERT(shared->is_compiled()); 665 ASSERT(shared->is_compiled());
651 shared->set_code_age(0); 666 shared->set_code_age(0);
652 667
653 if (V8::UseCrankshaft() && info->AllowOptimize()) { 668 if (V8::UseCrankshaft() && info->AllowOptimize()) {
654 // If we're asked to always optimize, we compile the optimized 669 // If we're asked to always optimize, we compile the optimized
655 // version of the function right away - unless the debugger is 670 // version of the function right away - unless the debugger is
656 // active as it makes no sense to compile optimized code then. 671 // active as it makes no sense to compile optimized code then.
657 if (FLAG_always_opt && !Debug::has_break_points()) { 672 if (FLAG_always_opt &&
673 !Isolate::Current()->debug()->has_break_points()) {
658 CompilationInfo optimized(function); 674 CompilationInfo optimized(function);
659 optimized.SetOptimizing(AstNode::kNoNumber); 675 optimized.SetOptimizing(AstNode::kNoNumber);
660 return CompileLazy(&optimized); 676 return CompileLazy(&optimized);
661 } else if (CompilationCache::ShouldOptimizeEagerly(function)) { 677 } else if (isolate->compilation_cache()->ShouldOptimizeEagerly(
662 RuntimeProfiler::OptimizeSoon(*function); 678 function)) {
679 isolate->runtime_profiler()->OptimizeSoon(*function);
663 } 680 }
664 } 681 }
665 } 682 }
666 683
667 return true; 684 return true;
668 } 685 }
669 } 686 }
670 687
671 ASSERT(info->code().is_null()); 688 ASSERT(info->code().is_null());
672 return false; 689 return false;
673 } 690 }
674 691
675 692
676 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 693 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
677 Handle<Script> script) { 694 Handle<Script> script) {
678 // Precondition: code has been parsed and scopes have been analyzed. 695 // Precondition: code has been parsed and scopes have been analyzed.
679 CompilationInfo info(script); 696 CompilationInfo info(script);
680 info.SetFunction(literal); 697 info.SetFunction(literal);
681 info.SetScope(literal->scope()); 698 info.SetScope(literal->scope());
682 699
683 LiveEditFunctionTracker live_edit_tracker(literal); 700 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
684 // Determine if the function can be lazily compiled. This is necessary to 701 // Determine if the function can be lazily compiled. This is necessary to
685 // allow some of our builtin JS files to be lazily compiled. These 702 // allow some of our builtin JS files to be lazily compiled. These
686 // builtins cannot be handled lazily by the parser, since we have to know 703 // builtins cannot be handled lazily by the parser, since we have to know
687 // if a function uses the special natives syntax, which is something the 704 // if a function uses the special natives syntax, which is something the
688 // parser records. 705 // parser records.
689 bool allow_lazy = literal->AllowsLazyCompilation() && 706 bool allow_lazy = literal->AllowsLazyCompilation() &&
690 !LiveEditFunctionTracker::IsActive(); 707 !LiveEditFunctionTracker::IsActive(info.isolate());
691 708
692 Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty()); 709 Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
693 710
694 // Generate code 711 // Generate code
695 if (FLAG_lazy && allow_lazy) { 712 if (FLAG_lazy && allow_lazy) {
696 Handle<Code> code(Builtins::builtin(Builtins::LazyCompile)); 713 Handle<Code> code(
714 info.isolate()->builtins()->builtin(Builtins::LazyCompile));
697 info.SetCode(code); 715 info.SetCode(code);
698 } else { 716 } else {
699 if (V8::UseCrankshaft()) { 717 if (V8::UseCrankshaft()) {
700 if (!MakeCrankshaftCode(&info)) { 718 if (!MakeCrankshaftCode(&info)) {
701 return Handle<SharedFunctionInfo>::null(); 719 return Handle<SharedFunctionInfo>::null();
702 } 720 }
703 } else { 721 } else {
704 // The bodies of function literals have not yet been visited by the 722 // The bodies of function literals have not yet been visited by the
705 // AST optimizer/analyzer. 723 // AST optimizer/analyzer.
706 if (!Rewriter::Analyze(&info)) return Handle<SharedFunctionInfo>::null(); 724 if (!Rewriter::Analyze(&info)) return Handle<SharedFunctionInfo>::null();
(...skipping 14 matching lines...) Expand all
721 } 739 }
722 } 740 }
723 ASSERT(!info.code().is_null()); 741 ASSERT(!info.code().is_null());
724 742
725 // Function compilation complete. 743 // Function compilation complete.
726 scope_info = SerializedScopeInfo::Create(info.scope()); 744 scope_info = SerializedScopeInfo::Create(info.scope());
727 } 745 }
728 746
729 // Create a shared function info object. 747 // Create a shared function info object.
730 Handle<SharedFunctionInfo> result = 748 Handle<SharedFunctionInfo> result =
731 Factory::NewSharedFunctionInfo(literal->name(), 749 FACTORY->NewSharedFunctionInfo(literal->name(),
732 literal->materialized_literal_count(), 750 literal->materialized_literal_count(),
733 info.code(), 751 info.code(),
734 scope_info); 752 scope_info);
735 SetFunctionInfo(result, literal, false, script); 753 SetFunctionInfo(result, literal, false, script);
736 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); 754 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
737 result->set_allows_lazy_compilation(allow_lazy); 755 result->set_allows_lazy_compilation(allow_lazy);
738 756
739 // Set the expected number of properties for instances and return 757 // Set the expected number of properties for instances and return
740 // the resulting function. 758 // the resulting function.
741 SetExpectedNofPropertiesFromEstimate(result, 759 SetExpectedNofPropertiesFromEstimate(result,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 791
774 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, 792 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
775 CompilationInfo* info, 793 CompilationInfo* info,
776 Handle<SharedFunctionInfo> shared) { 794 Handle<SharedFunctionInfo> shared) {
777 // SharedFunctionInfo is passed separately, because if CompilationInfo 795 // SharedFunctionInfo is passed separately, because if CompilationInfo
778 // was created using Script object, it will not have it. 796 // was created using Script object, it will not have it.
779 797
780 // Log the code generation. If source information is available include 798 // Log the code generation. If source information is available include
781 // script name and line number. Check explicitly whether logging is 799 // script name and line number. Check explicitly whether logging is
782 // enabled as finding the line number is not free. 800 // enabled as finding the line number is not free.
783 if (Logger::is_logging() || CpuProfiler::is_profiling()) { 801 if (info->isolate()->logger()->is_logging() || CpuProfiler::is_profiling()) {
784 Handle<Script> script = info->script(); 802 Handle<Script> script = info->script();
785 Handle<Code> code = info->code(); 803 Handle<Code> code = info->code();
786 if (*code == Builtins::builtin(Builtins::LazyCompile)) return; 804 if (*code == info->isolate()->builtins()->builtin(Builtins::LazyCompile))
805 return;
787 if (script->name()->IsString()) { 806 if (script->name()->IsString()) {
788 int line_num = GetScriptLineNumber(script, shared->start_position()) + 1; 807 int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
789 USE(line_num); 808 USE(line_num);
790 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 809 PROFILE(info->isolate(),
810 CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
791 *code, 811 *code,
792 *shared, 812 *shared,
793 String::cast(script->name()), 813 String::cast(script->name()),
794 line_num)); 814 line_num));
795 } else { 815 } else {
796 PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 816 PROFILE(info->isolate(),
817 CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
797 *code, 818 *code,
798 *shared, 819 *shared,
799 shared->DebugName())); 820 shared->DebugName()));
800 } 821 }
801 } 822 }
802 823
803 GDBJIT(AddCode(name, 824 GDBJIT(AddCode(name,
804 Handle<Script>(info->script()), 825 Handle<Script>(info->script()),
805 Handle<Code>(info->code()))); 826 Handle<Code>(info->code())));
806 } 827 }
807 828
808 } } // namespace v8::internal 829 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698