| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "src/vm-state-inl.h" | 29 #include "src/vm-state-inl.h" |
| 30 | 30 |
| 31 namespace v8 { | 31 namespace v8 { |
| 32 namespace internal { | 32 namespace internal { |
| 33 | 33 |
| 34 | 34 |
| 35 ScriptData::ScriptData(const byte* data, int length) | 35 ScriptData::ScriptData(const byte* data, int length) |
| 36 : owns_data_(false), data_(data), length_(length) { | 36 : owns_data_(false), data_(data), length_(length) { |
| 37 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { | 37 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { |
| 38 byte* copy = NewArray<byte>(length); | 38 byte* copy = NewArray<byte>(length); |
| 39 ASSERT(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); | 39 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); |
| 40 CopyBytes(copy, data, length); | 40 CopyBytes(copy, data, length); |
| 41 data_ = copy; | 41 data_ = copy; |
| 42 AcquireDataOwnership(); | 42 AcquireDataOwnership(); |
| 43 } | 43 } |
| 44 } | 44 } |
| 45 | 45 |
| 46 | 46 |
| 47 CompilationInfo::CompilationInfo(Handle<Script> script, | 47 CompilationInfo::CompilationInfo(Handle<Script> script, |
| 48 Zone* zone) | 48 Zone* zone) |
| 49 : flags_(StrictModeField::encode(SLOPPY)), | 49 : flags_(StrictModeField::encode(SLOPPY)), |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 if (mode == STUB) { | 141 if (mode == STUB) { |
| 142 mode_ = STUB; | 142 mode_ = STUB; |
| 143 return; | 143 return; |
| 144 } | 144 } |
| 145 mode_ = mode; | 145 mode_ = mode; |
| 146 abort_due_to_dependency_ = false; | 146 abort_due_to_dependency_ = false; |
| 147 if (script_->type()->value() == Script::TYPE_NATIVE) MarkAsNative(); | 147 if (script_->type()->value() == Script::TYPE_NATIVE) MarkAsNative(); |
| 148 if (isolate_->debug()->is_active()) MarkAsDebug(); | 148 if (isolate_->debug()->is_active()) MarkAsDebug(); |
| 149 | 149 |
| 150 if (!shared_info_.is_null()) { | 150 if (!shared_info_.is_null()) { |
| 151 ASSERT(strict_mode() == SLOPPY); | 151 DCHECK(strict_mode() == SLOPPY); |
| 152 SetStrictMode(shared_info_->strict_mode()); | 152 SetStrictMode(shared_info_->strict_mode()); |
| 153 } | 153 } |
| 154 set_bailout_reason(kUnknown); | 154 set_bailout_reason(kUnknown); |
| 155 | 155 |
| 156 if (!shared_info().is_null() && shared_info()->is_compiled()) { | 156 if (!shared_info().is_null() && shared_info()->is_compiled()) { |
| 157 // We should initialize the CompilationInfo feedback vector from the | 157 // We should initialize the CompilationInfo feedback vector from the |
| 158 // passed in shared info, rather than creating a new one. | 158 // passed in shared info, rather than creating a new one. |
| 159 feedback_vector_ = Handle<FixedArray>(shared_info()->feedback_vector(), | 159 feedback_vector_ = Handle<FixedArray>(shared_info()->feedback_vector(), |
| 160 isolate); | 160 isolate); |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 | 163 |
| 164 | 164 |
| 165 CompilationInfo::~CompilationInfo() { | 165 CompilationInfo::~CompilationInfo() { |
| 166 delete deferred_handles_; | 166 delete deferred_handles_; |
| 167 delete no_frame_ranges_; | 167 delete no_frame_ranges_; |
| 168 if (ast_value_factory_owned_) delete ast_value_factory_; | 168 if (ast_value_factory_owned_) delete ast_value_factory_; |
| 169 #ifdef DEBUG | 169 #ifdef DEBUG |
| 170 // Check that no dependent maps have been added or added dependent maps have | 170 // Check that no dependent maps have been added or added dependent maps have |
| 171 // been rolled back or committed. | 171 // been rolled back or committed. |
| 172 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 172 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
| 173 ASSERT_EQ(NULL, dependencies_[i]); | 173 DCHECK_EQ(NULL, dependencies_[i]); |
| 174 } | 174 } |
| 175 #endif // DEBUG | 175 #endif // DEBUG |
| 176 } | 176 } |
| 177 | 177 |
| 178 | 178 |
| 179 void CompilationInfo::CommitDependencies(Handle<Code> code) { | 179 void CompilationInfo::CommitDependencies(Handle<Code> code) { |
| 180 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 180 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
| 181 ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i]; | 181 ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i]; |
| 182 if (group_objects == NULL) continue; | 182 if (group_objects == NULL) continue; |
| 183 ASSERT(!object_wrapper_.is_null()); | 183 DCHECK(!object_wrapper_.is_null()); |
| 184 for (int j = 0; j < group_objects->length(); j++) { | 184 for (int j = 0; j < group_objects->length(); j++) { |
| 185 DependentCode::DependencyGroup group = | 185 DependentCode::DependencyGroup group = |
| 186 static_cast<DependentCode::DependencyGroup>(i); | 186 static_cast<DependentCode::DependencyGroup>(i); |
| 187 DependentCode* dependent_code = | 187 DependentCode* dependent_code = |
| 188 DependentCode::ForObject(group_objects->at(j), group); | 188 DependentCode::ForObject(group_objects->at(j), group); |
| 189 dependent_code->UpdateToFinishedCode(group, this, *code); | 189 dependent_code->UpdateToFinishedCode(group, this, *code); |
| 190 } | 190 } |
| 191 dependencies_[i] = NULL; // Zone-allocated, no need to delete. | 191 dependencies_[i] = NULL; // Zone-allocated, no need to delete. |
| 192 } | 192 } |
| 193 } | 193 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 205 DependentCode::ForObject(group_objects->at(j), group); | 205 DependentCode::ForObject(group_objects->at(j), group); |
| 206 dependent_code->RemoveCompilationInfo(group, this); | 206 dependent_code->RemoveCompilationInfo(group, this); |
| 207 } | 207 } |
| 208 dependencies_[i] = NULL; // Zone-allocated, no need to delete. | 208 dependencies_[i] = NULL; // Zone-allocated, no need to delete. |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 | 211 |
| 212 | 212 |
| 213 int CompilationInfo::num_parameters() const { | 213 int CompilationInfo::num_parameters() const { |
| 214 if (IsStub()) { | 214 if (IsStub()) { |
| 215 ASSERT(parameter_count_ > 0); | 215 DCHECK(parameter_count_ > 0); |
| 216 return parameter_count_; | 216 return parameter_count_; |
| 217 } else { | 217 } else { |
| 218 return scope()->num_parameters(); | 218 return scope()->num_parameters(); |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 | 221 |
| 222 | 222 |
| 223 int CompilationInfo::num_heap_slots() const { | 223 int CompilationInfo::num_heap_slots() const { |
| 224 if (IsStub()) { | 224 if (IsStub()) { |
| 225 return 0; | 225 return 0; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 bool CompilationInfo::ShouldSelfOptimize() { | 259 bool CompilationInfo::ShouldSelfOptimize() { |
| 260 return FLAG_crankshaft && | 260 return FLAG_crankshaft && |
| 261 !function()->flags()->Contains(kDontSelfOptimize) && | 261 !function()->flags()->Contains(kDontSelfOptimize) && |
| 262 !function()->dont_optimize() && | 262 !function()->dont_optimize() && |
| 263 function()->scope()->AllowsLazyCompilation() && | 263 function()->scope()->AllowsLazyCompilation() && |
| 264 (shared_info().is_null() || !shared_info()->optimization_disabled()); | 264 (shared_info().is_null() || !shared_info()->optimization_disabled()); |
| 265 } | 265 } |
| 266 | 266 |
| 267 | 267 |
| 268 void CompilationInfo::PrepareForCompilation(Scope* scope) { | 268 void CompilationInfo::PrepareForCompilation(Scope* scope) { |
| 269 ASSERT(scope_ == NULL); | 269 DCHECK(scope_ == NULL); |
| 270 scope_ = scope; | 270 scope_ = scope; |
| 271 | 271 |
| 272 int length = function()->slot_count(); | 272 int length = function()->slot_count(); |
| 273 if (feedback_vector_.is_null()) { | 273 if (feedback_vector_.is_null()) { |
| 274 // Allocate the feedback vector too. | 274 // Allocate the feedback vector too. |
| 275 feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(length); | 275 feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(length); |
| 276 } | 276 } |
| 277 ASSERT(feedback_vector_->length() == length); | 277 DCHECK(feedback_vector_->length() == length); |
| 278 } | 278 } |
| 279 | 279 |
| 280 | 280 |
| 281 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder { | 281 class HOptimizedGraphBuilderWithPositions: public HOptimizedGraphBuilder { |
| 282 public: | 282 public: |
| 283 explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) | 283 explicit HOptimizedGraphBuilderWithPositions(CompilationInfo* info) |
| 284 : HOptimizedGraphBuilder(info) { | 284 : HOptimizedGraphBuilder(info) { |
| 285 } | 285 } |
| 286 | 286 |
| 287 #define DEF_VISIT(type) \ | 287 #define DEF_VISIT(type) \ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 308 virtual void Visit##type(type* node) V8_OVERRIDE { \ | 308 virtual void Visit##type(type* node) V8_OVERRIDE { \ |
| 309 HOptimizedGraphBuilder::Visit##type(node); \ | 309 HOptimizedGraphBuilder::Visit##type(node); \ |
| 310 } | 310 } |
| 311 MODULE_NODE_LIST(DEF_VISIT) | 311 MODULE_NODE_LIST(DEF_VISIT) |
| 312 DECLARATION_NODE_LIST(DEF_VISIT) | 312 DECLARATION_NODE_LIST(DEF_VISIT) |
| 313 #undef DEF_VISIT | 313 #undef DEF_VISIT |
| 314 }; | 314 }; |
| 315 | 315 |
| 316 | 316 |
| 317 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { | 317 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() { |
| 318 ASSERT(isolate()->use_crankshaft()); | 318 DCHECK(isolate()->use_crankshaft()); |
| 319 ASSERT(info()->IsOptimizing()); | 319 DCHECK(info()->IsOptimizing()); |
| 320 ASSERT(!info()->IsCompilingForDebugging()); | 320 DCHECK(!info()->IsCompilingForDebugging()); |
| 321 | 321 |
| 322 // We should never arrive here if there is no code object on the | 322 // We should never arrive here if there is no code object on the |
| 323 // shared function object. | 323 // shared function object. |
| 324 ASSERT(info()->shared_info()->code()->kind() == Code::FUNCTION); | 324 DCHECK(info()->shared_info()->code()->kind() == Code::FUNCTION); |
| 325 | 325 |
| 326 // We should never arrive here if optimization has been disabled on the | 326 // We should never arrive here if optimization has been disabled on the |
| 327 // shared function info. | 327 // shared function info. |
| 328 ASSERT(!info()->shared_info()->optimization_disabled()); | 328 DCHECK(!info()->shared_info()->optimization_disabled()); |
| 329 | 329 |
| 330 // Fall back to using the full code generator if it's not possible | 330 // Fall back to using the full code generator if it's not possible |
| 331 // to use the Hydrogen-based optimizing compiler. We already have | 331 // to use the Hydrogen-based optimizing compiler. We already have |
| 332 // generated code for this from the shared function object. | 332 // generated code for this from the shared function object. |
| 333 if (FLAG_always_full_compiler) return AbortOptimization(); | 333 if (FLAG_always_full_compiler) return AbortOptimization(); |
| 334 | 334 |
| 335 // Do not use crankshaft if we need to be able to set break points. | 335 // Do not use crankshaft if we need to be able to set break points. |
| 336 if (isolate()->DebuggerHasBreakPoints()) { | 336 if (isolate()->DebuggerHasBreakPoints()) { |
| 337 return AbortOptimization(kDebuggerHasBreakPoints); | 337 return AbortOptimization(kDebuggerHasBreakPoints); |
| 338 } | 338 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 shared->EnableDeoptimizationSupport(*unoptimized.code()); | 398 shared->EnableDeoptimizationSupport(*unoptimized.code()); |
| 399 // The existing unoptimized code was replaced with the new one. | 399 // The existing unoptimized code was replaced with the new one. |
| 400 Compiler::RecordFunctionCompilation( | 400 Compiler::RecordFunctionCompilation( |
| 401 Logger::LAZY_COMPILE_TAG, &unoptimized, shared); | 401 Logger::LAZY_COMPILE_TAG, &unoptimized, shared); |
| 402 } | 402 } |
| 403 if (FLAG_hydrogen_stats) { | 403 if (FLAG_hydrogen_stats) { |
| 404 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); | 404 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed()); |
| 405 } | 405 } |
| 406 } | 406 } |
| 407 | 407 |
| 408 ASSERT(info()->shared_info()->has_deoptimization_support()); | 408 DCHECK(info()->shared_info()->has_deoptimization_support()); |
| 409 | 409 |
| 410 // Check the whitelist for TurboFan. | 410 // Check the whitelist for TurboFan. |
| 411 if (info()->closure()->PassesFilter(FLAG_turbo_filter) && | 411 if (info()->closure()->PassesFilter(FLAG_turbo_filter) && |
| 412 // TODO(turbofan): Make try-catch work and remove this bailout. | 412 // TODO(turbofan): Make try-catch work and remove this bailout. |
| 413 info()->function()->dont_optimize_reason() != kTryCatchStatement && | 413 info()->function()->dont_optimize_reason() != kTryCatchStatement && |
| 414 info()->function()->dont_optimize_reason() != kTryFinallyStatement && | 414 info()->function()->dont_optimize_reason() != kTryFinallyStatement && |
| 415 // TODO(turbofan): Make OSR work and remove this bailout. | 415 // TODO(turbofan): Make OSR work and remove this bailout. |
| 416 !info()->is_osr()) { | 416 !info()->is_osr()) { |
| 417 compiler::Pipeline pipeline(info()); | 417 compiler::Pipeline pipeline(info()); |
| 418 pipeline.GenerateCode(); | 418 pipeline.GenerateCode(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 439 info()->set_this_has_uses(false); | 439 info()->set_this_has_uses(false); |
| 440 graph_ = graph_builder_->CreateGraph(); | 440 graph_ = graph_builder_->CreateGraph(); |
| 441 | 441 |
| 442 if (isolate()->has_pending_exception()) { | 442 if (isolate()->has_pending_exception()) { |
| 443 return SetLastStatus(FAILED); | 443 return SetLastStatus(FAILED); |
| 444 } | 444 } |
| 445 | 445 |
| 446 // The function being compiled may have bailed out due to an inline | 446 // The function being compiled may have bailed out due to an inline |
| 447 // candidate bailing out. In such a case, we don't disable | 447 // candidate bailing out. In such a case, we don't disable |
| 448 // optimization on the shared_info. | 448 // optimization on the shared_info. |
| 449 ASSERT(!graph_builder_->inline_bailout() || graph_ == NULL); | 449 DCHECK(!graph_builder_->inline_bailout() || graph_ == NULL); |
| 450 if (graph_ == NULL) { | 450 if (graph_ == NULL) { |
| 451 if (graph_builder_->inline_bailout()) { | 451 if (graph_builder_->inline_bailout()) { |
| 452 return AbortOptimization(); | 452 return AbortOptimization(); |
| 453 } else { | 453 } else { |
| 454 return AbortAndDisableOptimization(); | 454 return AbortAndDisableOptimization(); |
| 455 } | 455 } |
| 456 } | 456 } |
| 457 | 457 |
| 458 if (info()->HasAbortedDueToDependencyChange()) { | 458 if (info()->HasAbortedDueToDependencyChange()) { |
| 459 return AbortOptimization(kBailedOutDueToDependencyChange); | 459 return AbortOptimization(kBailedOutDueToDependencyChange); |
| 460 } | 460 } |
| 461 | 461 |
| 462 return SetLastStatus(SUCCEEDED); | 462 return SetLastStatus(SUCCEEDED); |
| 463 } | 463 } |
| 464 | 464 |
| 465 | 465 |
| 466 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { | 466 OptimizedCompileJob::Status OptimizedCompileJob::OptimizeGraph() { |
| 467 DisallowHeapAllocation no_allocation; | 467 DisallowHeapAllocation no_allocation; |
| 468 DisallowHandleAllocation no_handles; | 468 DisallowHandleAllocation no_handles; |
| 469 DisallowHandleDereference no_deref; | 469 DisallowHandleDereference no_deref; |
| 470 DisallowCodeDependencyChange no_dependency_change; | 470 DisallowCodeDependencyChange no_dependency_change; |
| 471 | 471 |
| 472 ASSERT(last_status() == SUCCEEDED); | 472 DCHECK(last_status() == SUCCEEDED); |
| 473 // TODO(turbofan): Currently everything is done in the first phase. | 473 // TODO(turbofan): Currently everything is done in the first phase. |
| 474 if (!info()->code().is_null()) { | 474 if (!info()->code().is_null()) { |
| 475 return last_status(); | 475 return last_status(); |
| 476 } | 476 } |
| 477 | 477 |
| 478 Timer t(this, &time_taken_to_optimize_); | 478 Timer t(this, &time_taken_to_optimize_); |
| 479 ASSERT(graph_ != NULL); | 479 DCHECK(graph_ != NULL); |
| 480 BailoutReason bailout_reason = kNoReason; | 480 BailoutReason bailout_reason = kNoReason; |
| 481 | 481 |
| 482 if (graph_->Optimize(&bailout_reason)) { | 482 if (graph_->Optimize(&bailout_reason)) { |
| 483 chunk_ = LChunk::NewChunk(graph_); | 483 chunk_ = LChunk::NewChunk(graph_); |
| 484 if (chunk_ != NULL) return SetLastStatus(SUCCEEDED); | 484 if (chunk_ != NULL) return SetLastStatus(SUCCEEDED); |
| 485 } else if (bailout_reason != kNoReason) { | 485 } else if (bailout_reason != kNoReason) { |
| 486 graph_builder_->Bailout(bailout_reason); | 486 graph_builder_->Bailout(bailout_reason); |
| 487 } | 487 } |
| 488 | 488 |
| 489 return AbortOptimization(); | 489 return AbortOptimization(); |
| 490 } | 490 } |
| 491 | 491 |
| 492 | 492 |
| 493 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { | 493 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { |
| 494 ASSERT(last_status() == SUCCEEDED); | 494 DCHECK(last_status() == SUCCEEDED); |
| 495 // TODO(turbofan): Currently everything is done in the first phase. | 495 // TODO(turbofan): Currently everything is done in the first phase. |
| 496 if (!info()->code().is_null()) { | 496 if (!info()->code().is_null()) { |
| 497 RecordOptimizationStats(); | 497 RecordOptimizationStats(); |
| 498 return last_status(); | 498 return last_status(); |
| 499 } | 499 } |
| 500 | 500 |
| 501 ASSERT(!info()->HasAbortedDueToDependencyChange()); | 501 DCHECK(!info()->HasAbortedDueToDependencyChange()); |
| 502 DisallowCodeDependencyChange no_dependency_change; | 502 DisallowCodeDependencyChange no_dependency_change; |
| 503 DisallowJavascriptExecution no_js(isolate()); | 503 DisallowJavascriptExecution no_js(isolate()); |
| 504 { // Scope for timer. | 504 { // Scope for timer. |
| 505 Timer timer(this, &time_taken_to_codegen_); | 505 Timer timer(this, &time_taken_to_codegen_); |
| 506 ASSERT(chunk_ != NULL); | 506 DCHECK(chunk_ != NULL); |
| 507 ASSERT(graph_ != NULL); | 507 DCHECK(graph_ != NULL); |
| 508 // Deferred handles reference objects that were accessible during | 508 // Deferred handles reference objects that were accessible during |
| 509 // graph creation. To make sure that we don't encounter inconsistencies | 509 // graph creation. To make sure that we don't encounter inconsistencies |
| 510 // between graph creation and code generation, we disallow accessing | 510 // between graph creation and code generation, we disallow accessing |
| 511 // objects through deferred handles during the latter, with exceptions. | 511 // objects through deferred handles during the latter, with exceptions. |
| 512 DisallowDeferredHandleDereference no_deferred_handle_deref; | 512 DisallowDeferredHandleDereference no_deferred_handle_deref; |
| 513 Handle<Code> optimized_code = chunk_->Codegen(); | 513 Handle<Code> optimized_code = chunk_->Codegen(); |
| 514 if (optimized_code.is_null()) { | 514 if (optimized_code.is_null()) { |
| 515 if (info()->bailout_reason() == kNoReason) { | 515 if (info()->bailout_reason() == kNoReason) { |
| 516 info_->set_bailout_reason(kCodeGenerationFailed); | 516 info_->set_bailout_reason(kCodeGenerationFailed); |
| 517 } else if (info()->bailout_reason() == kMapBecameDeprecated) { | 517 } else if (info()->bailout_reason() == kMapBecameDeprecated) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 } | 598 } |
| 599 | 599 |
| 600 shared->set_expected_nof_properties(estimate); | 600 shared->set_expected_nof_properties(estimate); |
| 601 } | 601 } |
| 602 | 602 |
| 603 | 603 |
| 604 static void UpdateSharedFunctionInfo(CompilationInfo* info) { | 604 static void UpdateSharedFunctionInfo(CompilationInfo* info) { |
| 605 // Update the shared function info with the compiled code and the | 605 // Update the shared function info with the compiled code and the |
| 606 // scope info. Please note, that the order of the shared function | 606 // scope info. Please note, that the order of the shared function |
| 607 // info initialization is important since set_scope_info might | 607 // info initialization is important since set_scope_info might |
| 608 // trigger a GC, causing the ASSERT below to be invalid if the code | 608 // trigger a GC, causing the DCHECK below to be invalid if the code |
| 609 // was flushed. By setting the code object last we avoid this. | 609 // was flushed. By setting the code object last we avoid this. |
| 610 Handle<SharedFunctionInfo> shared = info->shared_info(); | 610 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 611 Handle<ScopeInfo> scope_info = | 611 Handle<ScopeInfo> scope_info = |
| 612 ScopeInfo::Create(info->scope(), info->zone()); | 612 ScopeInfo::Create(info->scope(), info->zone()); |
| 613 shared->set_scope_info(*scope_info); | 613 shared->set_scope_info(*scope_info); |
| 614 | 614 |
| 615 Handle<Code> code = info->code(); | 615 Handle<Code> code = info->code(); |
| 616 CHECK(code->kind() == Code::FUNCTION); | 616 CHECK(code->kind() == Code::FUNCTION); |
| 617 shared->ReplaceCode(*code); | 617 shared->ReplaceCode(*code); |
| 618 if (shared->optimization_disabled()) code->set_optimizable(false); | 618 if (shared->optimization_disabled()) code->set_optimizable(false); |
| 619 | 619 |
| 620 shared->set_feedback_vector(*info->feedback_vector()); | 620 shared->set_feedback_vector(*info->feedback_vector()); |
| 621 | 621 |
| 622 // Set the expected number of properties for instances. | 622 // Set the expected number of properties for instances. |
| 623 FunctionLiteral* lit = info->function(); | 623 FunctionLiteral* lit = info->function(); |
| 624 int expected = lit->expected_property_count(); | 624 int expected = lit->expected_property_count(); |
| 625 SetExpectedNofPropertiesFromEstimate(shared, expected); | 625 SetExpectedNofPropertiesFromEstimate(shared, expected); |
| 626 | 626 |
| 627 // Check the function has compiled code. | 627 // Check the function has compiled code. |
| 628 ASSERT(shared->is_compiled()); | 628 DCHECK(shared->is_compiled()); |
| 629 shared->set_bailout_reason(lit->dont_optimize_reason()); | 629 shared->set_bailout_reason(lit->dont_optimize_reason()); |
| 630 shared->set_ast_node_count(lit->ast_node_count()); | 630 shared->set_ast_node_count(lit->ast_node_count()); |
| 631 shared->set_strict_mode(lit->strict_mode()); | 631 shared->set_strict_mode(lit->strict_mode()); |
| 632 } | 632 } |
| 633 | 633 |
| 634 | 634 |
| 635 // Sets the function info on a function. | 635 // Sets the function info on a function. |
| 636 // The start_position points to the first '(' character after the function name | 636 // The start_position points to the first '(' character after the function name |
| 637 // in the full script source. When counting characters in the script source the | 637 // in the full script source. When counting characters in the script source the |
| 638 // the first character is number 0 (not 1). | 638 // the first character is number 0 (not 1). |
| (...skipping 20 matching lines...) Expand all Loading... |
| 659 function_info->set_ast_node_count(lit->ast_node_count()); | 659 function_info->set_ast_node_count(lit->ast_node_count()); |
| 660 function_info->set_is_function(lit->is_function()); | 660 function_info->set_is_function(lit->is_function()); |
| 661 function_info->set_bailout_reason(lit->dont_optimize_reason()); | 661 function_info->set_bailout_reason(lit->dont_optimize_reason()); |
| 662 function_info->set_dont_cache(lit->flags()->Contains(kDontCache)); | 662 function_info->set_dont_cache(lit->flags()->Contains(kDontCache)); |
| 663 function_info->set_is_generator(lit->is_generator()); | 663 function_info->set_is_generator(lit->is_generator()); |
| 664 function_info->set_is_arrow(lit->is_arrow()); | 664 function_info->set_is_arrow(lit->is_arrow()); |
| 665 } | 665 } |
| 666 | 666 |
| 667 | 667 |
| 668 static bool CompileUnoptimizedCode(CompilationInfo* info) { | 668 static bool CompileUnoptimizedCode(CompilationInfo* info) { |
| 669 ASSERT(AllowCompilation::IsAllowed(info->isolate())); | 669 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
| 670 ASSERT(info->function() != NULL); | 670 DCHECK(info->function() != NULL); |
| 671 if (!Rewriter::Rewrite(info)) return false; | 671 if (!Rewriter::Rewrite(info)) return false; |
| 672 if (!Scope::Analyze(info)) return false; | 672 if (!Scope::Analyze(info)) return false; |
| 673 ASSERT(info->scope() != NULL); | 673 DCHECK(info->scope() != NULL); |
| 674 | 674 |
| 675 if (!FullCodeGenerator::MakeCode(info)) { | 675 if (!FullCodeGenerator::MakeCode(info)) { |
| 676 Isolate* isolate = info->isolate(); | 676 Isolate* isolate = info->isolate(); |
| 677 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 677 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 678 return false; | 678 return false; |
| 679 } | 679 } |
| 680 return true; | 680 return true; |
| 681 } | 681 } |
| 682 | 682 |
| 683 | 683 |
| 684 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 684 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
| 685 CompilationInfo* info) { | 685 CompilationInfo* info) { |
| 686 VMState<COMPILER> state(info->isolate()); | 686 VMState<COMPILER> state(info->isolate()); |
| 687 PostponeInterruptsScope postpone(info->isolate()); | 687 PostponeInterruptsScope postpone(info->isolate()); |
| 688 if (!Parser::Parse(info)) return MaybeHandle<Code>(); | 688 if (!Parser::Parse(info)) return MaybeHandle<Code>(); |
| 689 info->SetStrictMode(info->function()->strict_mode()); | 689 info->SetStrictMode(info->function()->strict_mode()); |
| 690 | 690 |
| 691 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 691 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
| 692 Compiler::RecordFunctionCompilation( | 692 Compiler::RecordFunctionCompilation( |
| 693 Logger::LAZY_COMPILE_TAG, info, info->shared_info()); | 693 Logger::LAZY_COMPILE_TAG, info, info->shared_info()); |
| 694 UpdateSharedFunctionInfo(info); | 694 UpdateSharedFunctionInfo(info); |
| 695 ASSERT_EQ(Code::FUNCTION, info->code()->kind()); | 695 DCHECK_EQ(Code::FUNCTION, info->code()->kind()); |
| 696 return info->code(); | 696 return info->code(); |
| 697 } | 697 } |
| 698 | 698 |
| 699 | 699 |
| 700 MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) { | 700 MaybeHandle<Code> Compiler::GetUnoptimizedCode(Handle<JSFunction> function) { |
| 701 ASSERT(!function->GetIsolate()->has_pending_exception()); | 701 DCHECK(!function->GetIsolate()->has_pending_exception()); |
| 702 ASSERT(!function->is_compiled()); | 702 DCHECK(!function->is_compiled()); |
| 703 if (function->shared()->is_compiled()) { | 703 if (function->shared()->is_compiled()) { |
| 704 return Handle<Code>(function->shared()->code()); | 704 return Handle<Code>(function->shared()->code()); |
| 705 } | 705 } |
| 706 | 706 |
| 707 CompilationInfoWithZone info(function); | 707 CompilationInfoWithZone info(function); |
| 708 Handle<Code> result; | 708 Handle<Code> result; |
| 709 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, | 709 ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result, |
| 710 GetUnoptimizedCodeCommon(&info), | 710 GetUnoptimizedCodeCommon(&info), |
| 711 Code); | 711 Code); |
| 712 | 712 |
| 713 if (FLAG_always_opt && | 713 if (FLAG_always_opt && |
| 714 info.isolate()->use_crankshaft() && | 714 info.isolate()->use_crankshaft() && |
| 715 !info.shared_info()->optimization_disabled() && | 715 !info.shared_info()->optimization_disabled() && |
| 716 !info.isolate()->DebuggerHasBreakPoints()) { | 716 !info.isolate()->DebuggerHasBreakPoints()) { |
| 717 Handle<Code> opt_code; | 717 Handle<Code> opt_code; |
| 718 if (Compiler::GetOptimizedCode( | 718 if (Compiler::GetOptimizedCode( |
| 719 function, result, | 719 function, result, |
| 720 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { | 720 Compiler::NOT_CONCURRENT).ToHandle(&opt_code)) { |
| 721 result = opt_code; | 721 result = opt_code; |
| 722 } | 722 } |
| 723 } | 723 } |
| 724 | 724 |
| 725 return result; | 725 return result; |
| 726 } | 726 } |
| 727 | 727 |
| 728 | 728 |
| 729 MaybeHandle<Code> Compiler::GetUnoptimizedCode( | 729 MaybeHandle<Code> Compiler::GetUnoptimizedCode( |
| 730 Handle<SharedFunctionInfo> shared) { | 730 Handle<SharedFunctionInfo> shared) { |
| 731 ASSERT(!shared->GetIsolate()->has_pending_exception()); | 731 DCHECK(!shared->GetIsolate()->has_pending_exception()); |
| 732 ASSERT(!shared->is_compiled()); | 732 DCHECK(!shared->is_compiled()); |
| 733 | 733 |
| 734 CompilationInfoWithZone info(shared); | 734 CompilationInfoWithZone info(shared); |
| 735 return GetUnoptimizedCodeCommon(&info); | 735 return GetUnoptimizedCodeCommon(&info); |
| 736 } | 736 } |
| 737 | 737 |
| 738 | 738 |
| 739 bool Compiler::EnsureCompiled(Handle<JSFunction> function, | 739 bool Compiler::EnsureCompiled(Handle<JSFunction> function, |
| 740 ClearExceptionFlag flag) { | 740 ClearExceptionFlag flag) { |
| 741 if (function->is_compiled()) return true; | 741 if (function->is_compiled()) return true; |
| 742 MaybeHandle<Code> maybe_code = Compiler::GetUnoptimizedCode(function); | 742 MaybeHandle<Code> maybe_code = Compiler::GetUnoptimizedCode(function); |
| 743 Handle<Code> code; | 743 Handle<Code> code; |
| 744 if (!maybe_code.ToHandle(&code)) { | 744 if (!maybe_code.ToHandle(&code)) { |
| 745 if (flag == CLEAR_EXCEPTION) { | 745 if (flag == CLEAR_EXCEPTION) { |
| 746 function->GetIsolate()->clear_pending_exception(); | 746 function->GetIsolate()->clear_pending_exception(); |
| 747 } | 747 } |
| 748 return false; | 748 return false; |
| 749 } | 749 } |
| 750 function->ReplaceCode(*code); | 750 function->ReplaceCode(*code); |
| 751 ASSERT(function->is_compiled()); | 751 DCHECK(function->is_compiled()); |
| 752 return true; | 752 return true; |
| 753 } | 753 } |
| 754 | 754 |
| 755 | 755 |
| 756 // Compile full code for debugging. This code will have debug break slots | 756 // Compile full code for debugging. This code will have debug break slots |
| 757 // and deoptimization information. Deoptimization information is required | 757 // and deoptimization information. Deoptimization information is required |
| 758 // in case that an optimized version of this function is still activated on | 758 // in case that an optimized version of this function is still activated on |
| 759 // the stack. It will also make sure that the full code is compiled with | 759 // the stack. It will also make sure that the full code is compiled with |
| 760 // the same flags as the previous version, that is flags which can change | 760 // the same flags as the previous version, that is flags which can change |
| 761 // the code generated. The current method of mapping from already compiled | 761 // the code generated. The current method of mapping from already compiled |
| 762 // full code without debug break slots to full code with debug break slots | 762 // full code without debug break slots to full code with debug break slots |
| 763 // depends on the generated code is otherwise exactly the same. | 763 // depends on the generated code is otherwise exactly the same. |
| 764 // If compilation fails, just keep the existing code. | 764 // If compilation fails, just keep the existing code. |
| 765 MaybeHandle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) { | 765 MaybeHandle<Code> Compiler::GetCodeForDebugging(Handle<JSFunction> function) { |
| 766 CompilationInfoWithZone info(function); | 766 CompilationInfoWithZone info(function); |
| 767 Isolate* isolate = info.isolate(); | 767 Isolate* isolate = info.isolate(); |
| 768 VMState<COMPILER> state(isolate); | 768 VMState<COMPILER> state(isolate); |
| 769 | 769 |
| 770 info.MarkAsDebug(); | 770 info.MarkAsDebug(); |
| 771 | 771 |
| 772 ASSERT(!isolate->has_pending_exception()); | 772 DCHECK(!isolate->has_pending_exception()); |
| 773 Handle<Code> old_code(function->shared()->code()); | 773 Handle<Code> old_code(function->shared()->code()); |
| 774 ASSERT(old_code->kind() == Code::FUNCTION); | 774 DCHECK(old_code->kind() == Code::FUNCTION); |
| 775 ASSERT(!old_code->has_debug_break_slots()); | 775 DCHECK(!old_code->has_debug_break_slots()); |
| 776 | 776 |
| 777 info.MarkCompilingForDebugging(); | 777 info.MarkCompilingForDebugging(); |
| 778 if (old_code->is_compiled_optimizable()) { | 778 if (old_code->is_compiled_optimizable()) { |
| 779 info.EnableDeoptimizationSupport(); | 779 info.EnableDeoptimizationSupport(); |
| 780 } else { | 780 } else { |
| 781 info.MarkNonOptimizable(); | 781 info.MarkNonOptimizable(); |
| 782 } | 782 } |
| 783 MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(&info); | 783 MaybeHandle<Code> maybe_new_code = GetUnoptimizedCodeCommon(&info); |
| 784 Handle<Code> new_code; | 784 Handle<Code> new_code; |
| 785 if (!maybe_new_code.ToHandle(&new_code)) { | 785 if (!maybe_new_code.ToHandle(&new_code)) { |
| 786 isolate->clear_pending_exception(); | 786 isolate->clear_pending_exception(); |
| 787 } else { | 787 } else { |
| 788 ASSERT_EQ(old_code->is_compiled_optimizable(), | 788 DCHECK_EQ(old_code->is_compiled_optimizable(), |
| 789 new_code->is_compiled_optimizable()); | 789 new_code->is_compiled_optimizable()); |
| 790 } | 790 } |
| 791 return maybe_new_code; | 791 return maybe_new_code; |
| 792 } | 792 } |
| 793 | 793 |
| 794 | 794 |
| 795 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 795 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 796 // TODO(635): support extensions. | 796 // TODO(635): support extensions. |
| 797 CompilationInfoWithZone info(script); | 797 CompilationInfoWithZone info(script); |
| 798 PostponeInterruptsScope postpone(info.isolate()); | 798 PostponeInterruptsScope postpone(info.isolate()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 816 static bool DebuggerWantsEagerCompilation(CompilationInfo* info, | 816 static bool DebuggerWantsEagerCompilation(CompilationInfo* info, |
| 817 bool allow_lazy_without_ctx = false) { | 817 bool allow_lazy_without_ctx = false) { |
| 818 return LiveEditFunctionTracker::IsActive(info->isolate()) || | 818 return LiveEditFunctionTracker::IsActive(info->isolate()) || |
| 819 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx); | 819 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx); |
| 820 } | 820 } |
| 821 | 821 |
| 822 | 822 |
| 823 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 823 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| 824 Isolate* isolate = info->isolate(); | 824 Isolate* isolate = info->isolate(); |
| 825 PostponeInterruptsScope postpone(isolate); | 825 PostponeInterruptsScope postpone(isolate); |
| 826 ASSERT(!isolate->native_context().is_null()); | 826 DCHECK(!isolate->native_context().is_null()); |
| 827 Handle<Script> script = info->script(); | 827 Handle<Script> script = info->script(); |
| 828 | 828 |
| 829 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 829 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
| 830 FixedArray* array = isolate->native_context()->embedder_data(); | 830 FixedArray* array = isolate->native_context()->embedder_data(); |
| 831 script->set_context_data(array->get(0)); | 831 script->set_context_data(array->get(0)); |
| 832 | 832 |
| 833 isolate->debug()->OnBeforeCompile(script); | 833 isolate->debug()->OnBeforeCompile(script); |
| 834 | 834 |
| 835 ASSERT(info->is_eval() || info->is_global()); | 835 DCHECK(info->is_eval() || info->is_global()); |
| 836 | 836 |
| 837 bool parse_allow_lazy = | 837 bool parse_allow_lazy = |
| 838 (info->compile_options() == ScriptCompiler::kConsumeParserCache || | 838 (info->compile_options() == ScriptCompiler::kConsumeParserCache || |
| 839 String::cast(script->source())->length() > FLAG_min_preparse_length) && | 839 String::cast(script->source())->length() > FLAG_min_preparse_length) && |
| 840 !DebuggerWantsEagerCompilation(info); | 840 !DebuggerWantsEagerCompilation(info); |
| 841 | 841 |
| 842 if (!parse_allow_lazy && | 842 if (!parse_allow_lazy && |
| 843 (info->compile_options() == ScriptCompiler::kProduceParserCache || | 843 (info->compile_options() == ScriptCompiler::kProduceParserCache || |
| 844 info->compile_options() == ScriptCompiler::kConsumeParserCache)) { | 844 info->compile_options() == ScriptCompiler::kConsumeParserCache)) { |
| 845 // We are going to parse eagerly, but we either 1) have cached data produced | 845 // We are going to parse eagerly, but we either 1) have cached data produced |
| (...skipping 22 matching lines...) Expand all Loading... |
| 868 ? info->isolate()->counters()->compile_eval() | 868 ? info->isolate()->counters()->compile_eval() |
| 869 : info->isolate()->counters()->compile(); | 869 : info->isolate()->counters()->compile(); |
| 870 HistogramTimerScope timer(rate); | 870 HistogramTimerScope timer(rate); |
| 871 | 871 |
| 872 // Compile the code. | 872 // Compile the code. |
| 873 if (!CompileUnoptimizedCode(info)) { | 873 if (!CompileUnoptimizedCode(info)) { |
| 874 return Handle<SharedFunctionInfo>::null(); | 874 return Handle<SharedFunctionInfo>::null(); |
| 875 } | 875 } |
| 876 | 876 |
| 877 // Allocate function. | 877 // Allocate function. |
| 878 ASSERT(!info->code().is_null()); | 878 DCHECK(!info->code().is_null()); |
| 879 result = isolate->factory()->NewSharedFunctionInfo( | 879 result = isolate->factory()->NewSharedFunctionInfo( |
| 880 lit->name(), lit->materialized_literal_count(), lit->is_generator(), | 880 lit->name(), lit->materialized_literal_count(), lit->is_generator(), |
| 881 lit->is_arrow(), info->code(), | 881 lit->is_arrow(), info->code(), |
| 882 ScopeInfo::Create(info->scope(), info->zone()), | 882 ScopeInfo::Create(info->scope(), info->zone()), |
| 883 info->feedback_vector()); | 883 info->feedback_vector()); |
| 884 | 884 |
| 885 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position()); | 885 DCHECK_EQ(RelocInfo::kNoPosition, lit->function_token_position()); |
| 886 SetFunctionInfo(result, lit, true, script); | 886 SetFunctionInfo(result, lit, true, script); |
| 887 | 887 |
| 888 Handle<String> script_name = script->name()->IsString() | 888 Handle<String> script_name = script->name()->IsString() |
| 889 ? Handle<String>(String::cast(script->name())) | 889 ? Handle<String>(String::cast(script->name())) |
| 890 : isolate->factory()->empty_string(); | 890 : isolate->factory()->empty_string(); |
| 891 Logger::LogEventsAndTags log_tag = info->is_eval() | 891 Logger::LogEventsAndTags log_tag = info->is_eval() |
| 892 ? Logger::EVAL_TAG | 892 ? Logger::EVAL_TAG |
| 893 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); | 893 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script); |
| 894 | 894 |
| 895 PROFILE(isolate, CodeCreateEvent( | 895 PROFILE(isolate, CodeCreateEvent( |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 shared_info = CompileToplevel(&info); | 944 shared_info = CompileToplevel(&info); |
| 945 | 945 |
| 946 if (shared_info.is_null()) { | 946 if (shared_info.is_null()) { |
| 947 return MaybeHandle<JSFunction>(); | 947 return MaybeHandle<JSFunction>(); |
| 948 } else { | 948 } else { |
| 949 // Explicitly disable optimization for eval code. We're not yet prepared | 949 // Explicitly disable optimization for eval code. We're not yet prepared |
| 950 // to handle eval-code in the optimizing compiler. | 950 // to handle eval-code in the optimizing compiler. |
| 951 shared_info->DisableOptimization(kEval); | 951 shared_info->DisableOptimization(kEval); |
| 952 | 952 |
| 953 // If caller is strict mode, the result must be in strict mode as well. | 953 // If caller is strict mode, the result must be in strict mode as well. |
| 954 ASSERT(strict_mode == SLOPPY || shared_info->strict_mode() == STRICT); | 954 DCHECK(strict_mode == SLOPPY || shared_info->strict_mode() == STRICT); |
| 955 if (!shared_info->dont_cache()) { | 955 if (!shared_info->dont_cache()) { |
| 956 compilation_cache->PutEval( | 956 compilation_cache->PutEval( |
| 957 source, context, shared_info, scope_position); | 957 source, context, shared_info, scope_position); |
| 958 } | 958 } |
| 959 } | 959 } |
| 960 } else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) { | 960 } else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) { |
| 961 shared_info->ResetForNewContext(isolate->heap()->global_ic_age()); | 961 shared_info->ResetForNewContext(isolate->heap()->global_ic_age()); |
| 962 } | 962 } |
| 963 | 963 |
| 964 return isolate->factory()->NewFunctionFromSharedFunctionInfo( | 964 return isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 965 shared_info, context, NOT_TENURED); | 965 shared_info, context, NOT_TENURED); |
| 966 } | 966 } |
| 967 | 967 |
| 968 | 968 |
| 969 Handle<SharedFunctionInfo> Compiler::CompileScript( | 969 Handle<SharedFunctionInfo> Compiler::CompileScript( |
| 970 Handle<String> source, Handle<Object> script_name, int line_offset, | 970 Handle<String> source, Handle<Object> script_name, int line_offset, |
| 971 int column_offset, bool is_shared_cross_origin, Handle<Context> context, | 971 int column_offset, bool is_shared_cross_origin, Handle<Context> context, |
| 972 v8::Extension* extension, ScriptData** cached_data, | 972 v8::Extension* extension, ScriptData** cached_data, |
| 973 ScriptCompiler::CompileOptions compile_options, NativesFlag natives) { | 973 ScriptCompiler::CompileOptions compile_options, NativesFlag natives) { |
| 974 if (compile_options == ScriptCompiler::kNoCompileOptions) { | 974 if (compile_options == ScriptCompiler::kNoCompileOptions) { |
| 975 cached_data = NULL; | 975 cached_data = NULL; |
| 976 } else if (compile_options == ScriptCompiler::kProduceParserCache || | 976 } else if (compile_options == ScriptCompiler::kProduceParserCache || |
| 977 compile_options == ScriptCompiler::kProduceCodeCache) { | 977 compile_options == ScriptCompiler::kProduceCodeCache) { |
| 978 ASSERT(cached_data && !*cached_data); | 978 DCHECK(cached_data && !*cached_data); |
| 979 ASSERT(extension == NULL); | 979 DCHECK(extension == NULL); |
| 980 } else { | 980 } else { |
| 981 ASSERT(compile_options == ScriptCompiler::kConsumeParserCache || | 981 DCHECK(compile_options == ScriptCompiler::kConsumeParserCache || |
| 982 compile_options == ScriptCompiler::kConsumeCodeCache); | 982 compile_options == ScriptCompiler::kConsumeCodeCache); |
| 983 ASSERT(cached_data && *cached_data); | 983 DCHECK(cached_data && *cached_data); |
| 984 ASSERT(extension == NULL); | 984 DCHECK(extension == NULL); |
| 985 } | 985 } |
| 986 Isolate* isolate = source->GetIsolate(); | 986 Isolate* isolate = source->GetIsolate(); |
| 987 int source_length = source->length(); | 987 int source_length = source->length(); |
| 988 isolate->counters()->total_load_size()->Increment(source_length); | 988 isolate->counters()->total_load_size()->Increment(source_length); |
| 989 isolate->counters()->total_compile_size()->Increment(source_length); | 989 isolate->counters()->total_compile_size()->Increment(source_length); |
| 990 | 990 |
| 991 CompilationCache* compilation_cache = isolate->compilation_cache(); | 991 CompilationCache* compilation_cache = isolate->compilation_cache(); |
| 992 | 992 |
| 993 // Do a lookup in the compilation cache but not for extensions. | 993 // Do a lookup in the compilation cache but not for extensions. |
| 994 MaybeHandle<SharedFunctionInfo> maybe_result; | 994 MaybeHandle<SharedFunctionInfo> maybe_result; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 bool allow_lazy = literal->AllowsLazyCompilation() && | 1085 bool allow_lazy = literal->AllowsLazyCompilation() && |
| 1086 !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx); | 1086 !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx); |
| 1087 | 1087 |
| 1088 // Generate code | 1088 // Generate code |
| 1089 Handle<ScopeInfo> scope_info; | 1089 Handle<ScopeInfo> scope_info; |
| 1090 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { | 1090 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { |
| 1091 Handle<Code> code = isolate->builtins()->CompileUnoptimized(); | 1091 Handle<Code> code = isolate->builtins()->CompileUnoptimized(); |
| 1092 info.SetCode(code); | 1092 info.SetCode(code); |
| 1093 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1093 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
| 1094 } else if (FullCodeGenerator::MakeCode(&info)) { | 1094 } else if (FullCodeGenerator::MakeCode(&info)) { |
| 1095 ASSERT(!info.code().is_null()); | 1095 DCHECK(!info.code().is_null()); |
| 1096 scope_info = ScopeInfo::Create(info.scope(), info.zone()); | 1096 scope_info = ScopeInfo::Create(info.scope(), info.zone()); |
| 1097 } else { | 1097 } else { |
| 1098 return Handle<SharedFunctionInfo>::null(); | 1098 return Handle<SharedFunctionInfo>::null(); |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 // Create a shared function info object. | 1101 // Create a shared function info object. |
| 1102 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( | 1102 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( |
| 1103 literal->name(), literal->materialized_literal_count(), | 1103 literal->name(), literal->materialized_literal_count(), |
| 1104 literal->is_generator(), literal->is_arrow(), info.code(), scope_info, | 1104 literal->is_generator(), literal->is_arrow(), info.code(), scope_info, |
| 1105 info.feedback_vector()); | 1105 info.feedback_vector()); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 } | 1165 } |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 | 1168 |
| 1169 static bool CompileOptimizedPrologue(CompilationInfo* info) { | 1169 static bool CompileOptimizedPrologue(CompilationInfo* info) { |
| 1170 if (!Parser::Parse(info)) return false; | 1170 if (!Parser::Parse(info)) return false; |
| 1171 info->SetStrictMode(info->function()->strict_mode()); | 1171 info->SetStrictMode(info->function()->strict_mode()); |
| 1172 | 1172 |
| 1173 if (!Rewriter::Rewrite(info)) return false; | 1173 if (!Rewriter::Rewrite(info)) return false; |
| 1174 if (!Scope::Analyze(info)) return false; | 1174 if (!Scope::Analyze(info)) return false; |
| 1175 ASSERT(info->scope() != NULL); | 1175 DCHECK(info->scope() != NULL); |
| 1176 return true; | 1176 return true; |
| 1177 } | 1177 } |
| 1178 | 1178 |
| 1179 | 1179 |
| 1180 static bool GetOptimizedCodeNow(CompilationInfo* info) { | 1180 static bool GetOptimizedCodeNow(CompilationInfo* info) { |
| 1181 if (!CompileOptimizedPrologue(info)) return false; | 1181 if (!CompileOptimizedPrologue(info)) return false; |
| 1182 | 1182 |
| 1183 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 1183 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| 1184 | 1184 |
| 1185 OptimizedCompileJob job(info); | 1185 OptimizedCompileJob job(info); |
| 1186 if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED) return false; | 1186 if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED) return false; |
| 1187 if (job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED) return false; | 1187 if (job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED) return false; |
| 1188 if (job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) return false; | 1188 if (job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) return false; |
| 1189 | 1189 |
| 1190 // Success! | 1190 // Success! |
| 1191 ASSERT(!info->isolate()->has_pending_exception()); | 1191 DCHECK(!info->isolate()->has_pending_exception()); |
| 1192 InsertCodeIntoOptimizedCodeMap(info); | 1192 InsertCodeIntoOptimizedCodeMap(info); |
| 1193 Compiler::RecordFunctionCompilation( | 1193 Compiler::RecordFunctionCompilation( |
| 1194 Logger::LAZY_COMPILE_TAG, info, info->shared_info()); | 1194 Logger::LAZY_COMPILE_TAG, info, info->shared_info()); |
| 1195 return true; | 1195 return true; |
| 1196 } | 1196 } |
| 1197 | 1197 |
| 1198 | 1198 |
| 1199 static bool GetOptimizedCodeLater(CompilationInfo* info) { | 1199 static bool GetOptimizedCodeLater(CompilationInfo* info) { |
| 1200 Isolate* isolate = info->isolate(); | 1200 Isolate* isolate = info->isolate(); |
| 1201 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { | 1201 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 ConcurrencyMode mode, | 1236 ConcurrencyMode mode, |
| 1237 BailoutId osr_ast_id) { | 1237 BailoutId osr_ast_id) { |
| 1238 Handle<Code> cached_code; | 1238 Handle<Code> cached_code; |
| 1239 if (GetCodeFromOptimizedCodeMap( | 1239 if (GetCodeFromOptimizedCodeMap( |
| 1240 function, osr_ast_id).ToHandle(&cached_code)) { | 1240 function, osr_ast_id).ToHandle(&cached_code)) { |
| 1241 return cached_code; | 1241 return cached_code; |
| 1242 } | 1242 } |
| 1243 | 1243 |
| 1244 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); | 1244 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(function)); |
| 1245 Isolate* isolate = info->isolate(); | 1245 Isolate* isolate = info->isolate(); |
| 1246 ASSERT(AllowCompilation::IsAllowed(isolate)); | 1246 DCHECK(AllowCompilation::IsAllowed(isolate)); |
| 1247 VMState<COMPILER> state(isolate); | 1247 VMState<COMPILER> state(isolate); |
| 1248 ASSERT(!isolate->has_pending_exception()); | 1248 DCHECK(!isolate->has_pending_exception()); |
| 1249 PostponeInterruptsScope postpone(isolate); | 1249 PostponeInterruptsScope postpone(isolate); |
| 1250 | 1250 |
| 1251 Handle<SharedFunctionInfo> shared = info->shared_info(); | 1251 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1252 ASSERT_NE(ScopeInfo::Empty(isolate), shared->scope_info()); | 1252 DCHECK_NE(ScopeInfo::Empty(isolate), shared->scope_info()); |
| 1253 int compiled_size = shared->end_position() - shared->start_position(); | 1253 int compiled_size = shared->end_position() - shared->start_position(); |
| 1254 isolate->counters()->total_compile_size()->Increment(compiled_size); | 1254 isolate->counters()->total_compile_size()->Increment(compiled_size); |
| 1255 current_code->set_profiler_ticks(0); | 1255 current_code->set_profiler_ticks(0); |
| 1256 | 1256 |
| 1257 info->SetOptimizing(osr_ast_id, current_code); | 1257 info->SetOptimizing(osr_ast_id, current_code); |
| 1258 | 1258 |
| 1259 if (mode == CONCURRENT) { | 1259 if (mode == CONCURRENT) { |
| 1260 if (GetOptimizedCodeLater(info.get())) { | 1260 if (GetOptimizedCodeLater(info.get())) { |
| 1261 info.Detach(); // The background recompile job owns this now. | 1261 info.Detach(); // The background recompile job owns this now. |
| 1262 return isolate->builtins()->InOptimizationQueue(); | 1262 return isolate->builtins()->InOptimizationQueue(); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 AllowHandleDereference allow_deref; | 1382 AllowHandleDereference allow_deref; |
| 1383 bool tracing_on = info()->IsStub() | 1383 bool tracing_on = info()->IsStub() |
| 1384 ? FLAG_trace_hydrogen_stubs | 1384 ? FLAG_trace_hydrogen_stubs |
| 1385 : (FLAG_trace_hydrogen && | 1385 : (FLAG_trace_hydrogen && |
| 1386 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1386 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
| 1387 return (tracing_on && | 1387 return (tracing_on && |
| 1388 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1388 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
| 1389 } | 1389 } |
| 1390 | 1390 |
| 1391 } } // namespace v8::internal | 1391 } } // namespace v8::internal |
| OLD | NEW |