OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |