| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 } | 79 } |
| 80 | 80 |
| 81 #define DEF_VISIT(type) \ | 81 #define DEF_VISIT(type) \ |
| 82 void Visit##type(type* node) override { \ | 82 void Visit##type(type* node) override { \ |
| 83 SourcePosition old_position = SourcePosition::Unknown(); \ | 83 SourcePosition old_position = SourcePosition::Unknown(); \ |
| 84 if (node->position() != kNoSourcePosition) { \ | 84 if (node->position() != kNoSourcePosition) { \ |
| 85 old_position = source_position(); \ | 85 old_position = source_position(); \ |
| 86 SetSourcePosition(node->position()); \ | 86 SetSourcePosition(node->position()); \ |
| 87 } \ | 87 } \ |
| 88 HOptimizedGraphBuilder::Visit##type(node); \ | 88 HOptimizedGraphBuilder::Visit##type(node); \ |
| 89 if (!old_position.IsUnknown()) { \ | 89 if (old_position.IsKnown()) { \ |
| 90 set_source_position(old_position); \ | 90 set_source_position(old_position); \ |
| 91 } \ | 91 } \ |
| 92 } | 92 } |
| 93 EXPRESSION_NODE_LIST(DEF_VISIT) | 93 EXPRESSION_NODE_LIST(DEF_VISIT) |
| 94 #undef DEF_VISIT | 94 #undef DEF_VISIT |
| 95 | 95 |
| 96 #define DEF_VISIT(type) \ | 96 #define DEF_VISIT(type) \ |
| 97 void Visit##type(type* node) override { \ | 97 void Visit##type(type* node) override { \ |
| 98 SourcePosition old_position = SourcePosition::Unknown(); \ | 98 SourcePosition old_position = SourcePosition::Unknown(); \ |
| 99 if (node->position() != kNoSourcePosition) { \ | 99 if (node->position() != kNoSourcePosition) { \ |
| 100 old_position = source_position(); \ | 100 old_position = source_position(); \ |
| 101 SetSourcePosition(node->position()); \ | 101 SetSourcePosition(node->position()); \ |
| 102 } \ | 102 } \ |
| 103 HOptimizedGraphBuilder::Visit##type(node); \ | 103 HOptimizedGraphBuilder::Visit##type(node); \ |
| 104 if (!old_position.IsUnknown()) { \ | 104 if (old_position.IsKnown()) { \ |
| 105 set_source_position(old_position); \ | 105 set_source_position(old_position); \ |
| 106 } \ | 106 } \ |
| 107 } | 107 } |
| 108 STATEMENT_NODE_LIST(DEF_VISIT) | 108 STATEMENT_NODE_LIST(DEF_VISIT) |
| 109 #undef DEF_VISIT | 109 #undef DEF_VISIT |
| 110 | 110 |
| 111 #define DEF_VISIT(type) \ | 111 #define DEF_VISIT(type) \ |
| 112 void Visit##type(type* node) override { \ | 112 void Visit##type(type* node) override { \ |
| 113 HOptimizedGraphBuilder::Visit##type(node); \ | 113 HOptimizedGraphBuilder::Visit##type(node); \ |
| 114 } | 114 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 phis_.RemoveElement(phi); | 305 phis_.RemoveElement(phi); |
| 306 phi->SetBlock(NULL); | 306 phi->SetBlock(NULL); |
| 307 } | 307 } |
| 308 | 308 |
| 309 | 309 |
| 310 void HBasicBlock::AddInstruction(HInstruction* instr, SourcePosition position) { | 310 void HBasicBlock::AddInstruction(HInstruction* instr, SourcePosition position) { |
| 311 DCHECK(!IsStartBlock() || !IsFinished()); | 311 DCHECK(!IsStartBlock() || !IsFinished()); |
| 312 DCHECK(!instr->IsLinked()); | 312 DCHECK(!instr->IsLinked()); |
| 313 DCHECK(!IsFinished()); | 313 DCHECK(!IsFinished()); |
| 314 | 314 |
| 315 if (!position.IsUnknown()) { | 315 if (position.IsKnown()) { |
| 316 instr->set_position(position); | 316 instr->set_position(position); |
| 317 } | 317 } |
| 318 if (first_ == NULL) { | 318 if (first_ == NULL) { |
| 319 DCHECK(last_environment() != NULL); | 319 DCHECK(last_environment() != NULL); |
| 320 DCHECK(!last_environment()->ast_id().IsNone()); | 320 DCHECK(!last_environment()->ast_id().IsNone()); |
| 321 HBlockEntry* entry = new(zone()) HBlockEntry(); | 321 HBlockEntry* entry = new(zone()) HBlockEntry(); |
| 322 entry->InitializeAsFirst(this); | 322 entry->InitializeAsFirst(this); |
| 323 if (!position.IsUnknown()) { | 323 if (position.IsKnown()) { |
| 324 entry->set_position(position); | 324 entry->set_position(position); |
| 325 } else { | 325 } else { |
| 326 DCHECK(!FLAG_hydrogen_track_positions || | 326 DCHECK(!FLAG_hydrogen_track_positions || |
| 327 !graph()->info()->IsOptimizing() || instr->IsAbnormalExit()); | 327 !graph()->info()->IsOptimizing() || instr->IsAbnormalExit()); |
| 328 } | 328 } |
| 329 first_ = last_ = entry; | 329 first_ = last_ = entry; |
| 330 } | 330 } |
| 331 instr->InsertAfter(last_); | 331 instr->InsertAfter(last_); |
| 332 } | 332 } |
| 333 | 333 |
| (...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 } | 1357 } |
| 1358 finished_ = true; | 1358 finished_ = true; |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 | 1361 |
| 1362 HGraph* HGraphBuilder::CreateGraph() { | 1362 HGraph* HGraphBuilder::CreateGraph() { |
| 1363 DCHECK(!FLAG_minimal); | 1363 DCHECK(!FLAG_minimal); |
| 1364 graph_ = new (zone()) HGraph(info_, descriptor_); | 1364 graph_ = new (zone()) HGraph(info_, descriptor_); |
| 1365 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); | 1365 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); |
| 1366 if (!info_->IsStub() && is_tracking_positions()) { | 1366 if (!info_->IsStub() && is_tracking_positions()) { |
| 1367 TraceInlinedFunction(info_->shared_info(), SourcePosition::Unknown()); | 1367 TraceInlinedFunction(info_->shared_info(), SourcePosition::Unknown(), |
| 1368 SourcePosition::kNotInlined); |
| 1368 } | 1369 } |
| 1369 CompilationPhase phase("H_Block building", info_); | 1370 CompilationPhase phase("H_Block building", info_); |
| 1370 set_current_block(graph()->entry_block()); | 1371 set_current_block(graph()->entry_block()); |
| 1371 if (!BuildGraph()) return NULL; | 1372 if (!BuildGraph()) return NULL; |
| 1372 graph()->FinalizeUniqueness(); | 1373 graph()->FinalizeUniqueness(); |
| 1373 return graph_; | 1374 return graph_; |
| 1374 } | 1375 } |
| 1375 | 1376 |
| 1376 int HGraphBuilder::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 1377 void HGraphBuilder::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
| 1377 SourcePosition position) { | 1378 SourcePosition position, |
| 1379 int inlining_id) { |
| 1378 DCHECK(is_tracking_positions()); | 1380 DCHECK(is_tracking_positions()); |
| 1379 | 1381 |
| 1380 int inline_id = static_cast<int>(graph()->inlined_function_infos().size()); | |
| 1381 HInlinedFunctionInfo info(shared->start_position()); | |
| 1382 if (!shared->script()->IsUndefined(isolate())) { | 1382 if (!shared->script()->IsUndefined(isolate())) { |
| 1383 Handle<Script> script(Script::cast(shared->script()), isolate()); | 1383 Handle<Script> script(Script::cast(shared->script()), isolate()); |
| 1384 | 1384 |
| 1385 if (FLAG_hydrogen_track_positions && | 1385 if (FLAG_hydrogen_track_positions && |
| 1386 !script->source()->IsUndefined(isolate())) { | 1386 !script->source()->IsUndefined(isolate())) { |
| 1387 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 1387 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
| 1388 Object* source_name = script->name(); | 1388 Object* source_name = script->name(); |
| 1389 OFStream os(tracing_scope.file()); | 1389 OFStream os(tracing_scope.file()); |
| 1390 os << "--- FUNCTION SOURCE ("; | 1390 os << "--- FUNCTION SOURCE ("; |
| 1391 if (source_name->IsString()) { | 1391 if (source_name->IsString()) { |
| 1392 os << String::cast(source_name)->ToCString().get() << ":"; | 1392 os << String::cast(source_name)->ToCString().get() << ":"; |
| 1393 } | 1393 } |
| 1394 os << shared->DebugName()->ToCString().get() << ") id{"; | 1394 os << shared->DebugName()->ToCString().get() << ") id{"; |
| 1395 os << info_->optimization_id() << "," << inline_id << "} ---\n"; | 1395 os << info_->optimization_id() << "," << inlining_id << "} ---\n"; |
| 1396 { | 1396 { |
| 1397 DisallowHeapAllocation no_allocation; | 1397 DisallowHeapAllocation no_allocation; |
| 1398 int start = shared->start_position(); | 1398 int start = shared->start_position(); |
| 1399 int len = shared->end_position() - start; | 1399 int len = shared->end_position() - start; |
| 1400 String::SubStringRange source(String::cast(script->source()), start, | 1400 String::SubStringRange source(String::cast(script->source()), start, |
| 1401 len); | 1401 len); |
| 1402 for (const auto& c : source) { | 1402 for (const auto& c : source) { |
| 1403 os << AsReversiblyEscapedUC16(c); | 1403 os << AsReversiblyEscapedUC16(c); |
| 1404 } | 1404 } |
| 1405 } | 1405 } |
| 1406 | 1406 |
| 1407 os << "\n--- END ---\n"; | 1407 os << "\n--- END ---\n"; |
| 1408 } | 1408 } |
| 1409 } | 1409 } |
| 1410 | 1410 |
| 1411 graph()->inlined_function_infos().push_back(info); | 1411 if (FLAG_hydrogen_track_positions && |
| 1412 | 1412 inlining_id != SourcePosition::kNotInlined) { |
| 1413 if (FLAG_hydrogen_track_positions && inline_id != 0) { | |
| 1414 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 1413 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
| 1415 OFStream os(tracing_scope.file()); | 1414 OFStream os(tracing_scope.file()); |
| 1416 os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{" | 1415 os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{" |
| 1417 << info_->optimization_id() << "," << inline_id << "} AS " << inline_id | 1416 << info_->optimization_id() << "," << inlining_id << "} AS " |
| 1418 << " AT " << position << std::endl; | 1417 << inlining_id << " AT " << position.ScriptOffset() << std::endl; |
| 1419 } | 1418 } |
| 1420 | |
| 1421 return inline_id; | |
| 1422 } | 1419 } |
| 1423 | 1420 |
| 1424 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 1421 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 1425 DCHECK(current_block() != NULL); | 1422 DCHECK(current_block() != NULL); |
| 1426 DCHECK(!FLAG_hydrogen_track_positions || | 1423 DCHECK(!FLAG_hydrogen_track_positions || position_.IsKnown() || |
| 1427 !position_.IsUnknown() || | |
| 1428 !info_->IsOptimizing()); | 1424 !info_->IsOptimizing()); |
| 1429 current_block()->AddInstruction(instr, source_position()); | 1425 current_block()->AddInstruction(instr, source_position()); |
| 1430 if (graph()->IsInsideNoSideEffectsScope()) { | 1426 if (graph()->IsInsideNoSideEffectsScope()) { |
| 1431 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 1427 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
| 1432 } | 1428 } |
| 1433 return instr; | 1429 return instr; |
| 1434 } | 1430 } |
| 1435 | 1431 |
| 1436 | 1432 |
| 1437 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { | 1433 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { |
| 1438 DCHECK(!FLAG_hydrogen_track_positions || | 1434 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || |
| 1439 !info_->IsOptimizing() || | 1435 position_.IsKnown()); |
| 1440 !position_.IsUnknown()); | |
| 1441 current_block()->Finish(last, source_position()); | 1436 current_block()->Finish(last, source_position()); |
| 1442 if (last->IsReturn() || last->IsAbnormalExit()) { | 1437 if (last->IsReturn() || last->IsAbnormalExit()) { |
| 1443 set_current_block(NULL); | 1438 set_current_block(NULL); |
| 1444 } | 1439 } |
| 1445 } | 1440 } |
| 1446 | 1441 |
| 1447 | 1442 |
| 1448 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { | 1443 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { |
| 1449 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || | 1444 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || |
| 1450 !position_.IsUnknown()); | 1445 position_.IsKnown()); |
| 1451 current_block()->FinishExit(instruction, source_position()); | 1446 current_block()->FinishExit(instruction, source_position()); |
| 1452 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { | 1447 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { |
| 1453 set_current_block(NULL); | 1448 set_current_block(NULL); |
| 1454 } | 1449 } |
| 1455 } | 1450 } |
| 1456 | 1451 |
| 1457 | 1452 |
| 1458 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { | 1453 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { |
| 1459 if (FLAG_native_code_counters && counter->Enabled()) { | 1454 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1460 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1455 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
| (...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3119 HValue* HGraphBuilder::AddLoadJSBuiltin(int context_index) { | 3114 HValue* HGraphBuilder::AddLoadJSBuiltin(int context_index) { |
| 3120 HValue* native_context = BuildGetNativeContext(); | 3115 HValue* native_context = BuildGetNativeContext(); |
| 3121 HObjectAccess function_access = HObjectAccess::ForContextSlot(context_index); | 3116 HObjectAccess function_access = HObjectAccess::ForContextSlot(context_index); |
| 3122 return Add<HLoadNamedField>(native_context, nullptr, function_access); | 3117 return Add<HLoadNamedField>(native_context, nullptr, function_access); |
| 3123 } | 3118 } |
| 3124 | 3119 |
| 3125 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 3120 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
| 3126 bool track_positions) | 3121 bool track_positions) |
| 3127 : HGraphBuilder(info, CallInterfaceDescriptor(), track_positions), | 3122 : HGraphBuilder(info, CallInterfaceDescriptor(), track_positions), |
| 3128 function_state_(NULL), | 3123 function_state_(NULL), |
| 3129 initial_function_state_(this, info, NORMAL_RETURN, 0, | 3124 initial_function_state_(this, info, NORMAL_RETURN, -1, |
| 3130 TailCallMode::kAllow), | 3125 TailCallMode::kAllow), |
| 3131 ast_context_(NULL), | 3126 ast_context_(NULL), |
| 3132 break_scope_(NULL), | 3127 break_scope_(NULL), |
| 3133 inlined_count_(0), | 3128 inlined_count_(0), |
| 3134 globals_(10, info->zone()), | 3129 globals_(10, info->zone()), |
| 3135 osr_(new (info->zone()) HOsrBuilder(this)), | 3130 osr_(new (info->zone()) HOsrBuilder(this)), |
| 3136 bounds_(info->zone()) { | 3131 bounds_(info->zone()) { |
| 3137 // This is not initialized in the initializer list because the | 3132 // This is not initialized in the initializer list because the |
| 3138 // constructor for the initial state relies on function_state_ == NULL | 3133 // constructor for the initial state relies on function_state_ == NULL |
| 3139 // to know it's the initial state. | 3134 // to know it's the initial state. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3235 info_(info), | 3230 info_(info), |
| 3236 descriptor_(descriptor), | 3231 descriptor_(descriptor), |
| 3237 zone_(info->zone()), | 3232 zone_(info->zone()), |
| 3238 allow_code_motion_(false), | 3233 allow_code_motion_(false), |
| 3239 use_optimistic_licm_(false), | 3234 use_optimistic_licm_(false), |
| 3240 depends_on_empty_array_proto_elements_(false), | 3235 depends_on_empty_array_proto_elements_(false), |
| 3241 depends_on_string_length_overflow_(false), | 3236 depends_on_string_length_overflow_(false), |
| 3242 type_change_checksum_(0), | 3237 type_change_checksum_(0), |
| 3243 maximum_environment_size_(0), | 3238 maximum_environment_size_(0), |
| 3244 no_side_effects_scope_count_(0), | 3239 no_side_effects_scope_count_(0), |
| 3245 disallow_adding_new_values_(false), | 3240 disallow_adding_new_values_(false) { |
| 3246 inlined_function_infos_(info->zone()) { | |
| 3247 if (info->IsStub()) { | 3241 if (info->IsStub()) { |
| 3248 // For stubs, explicitly add the context to the environment. | 3242 // For stubs, explicitly add the context to the environment. |
| 3249 start_environment_ = | 3243 start_environment_ = |
| 3250 new (zone_) HEnvironment(zone_, descriptor.GetParameterCount() + 1); | 3244 new (zone_) HEnvironment(zone_, descriptor.GetParameterCount() + 1); |
| 3251 } else { | 3245 } else { |
| 3252 start_environment_ = | 3246 start_environment_ = |
| 3253 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 3247 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| 3254 } | 3248 } |
| 3255 start_environment_->set_ast_id(BailoutId::FunctionContext()); | 3249 start_environment_->set_ast_id(BailoutId::FunctionContext()); |
| 3256 entry_block_ = CreateBasicBlock(); | 3250 entry_block_ = CreateBasicBlock(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3268 void HGraph::FinalizeUniqueness() { | 3262 void HGraph::FinalizeUniqueness() { |
| 3269 DisallowHeapAllocation no_gc; | 3263 DisallowHeapAllocation no_gc; |
| 3270 for (int i = 0; i < blocks()->length(); ++i) { | 3264 for (int i = 0; i < blocks()->length(); ++i) { |
| 3271 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { | 3265 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
| 3272 it.Current()->FinalizeUniqueness(); | 3266 it.Current()->FinalizeUniqueness(); |
| 3273 } | 3267 } |
| 3274 } | 3268 } |
| 3275 } | 3269 } |
| 3276 | 3270 |
| 3277 | 3271 |
| 3278 int HGraph::SourcePositionToScriptPosition(SourcePosition pos) { | |
| 3279 return (FLAG_hydrogen_track_positions && !pos.IsUnknown()) | |
| 3280 ? inlined_function_infos_.at(pos.inlining_id()).start_position + | |
| 3281 pos.position() | |
| 3282 : pos.raw(); | |
| 3283 } | |
| 3284 | |
| 3285 | |
| 3286 // Block ordering was implemented with two mutually recursive methods, | 3272 // Block ordering was implemented with two mutually recursive methods, |
| 3287 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 3273 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
| 3288 // The recursion could lead to stack overflow so the algorithm has been | 3274 // The recursion could lead to stack overflow so the algorithm has been |
| 3289 // implemented iteratively. | 3275 // implemented iteratively. |
| 3290 // At a high level the algorithm looks like this: | 3276 // At a high level the algorithm looks like this: |
| 3291 // | 3277 // |
| 3292 // Postorder(block, loop_header) : { | 3278 // Postorder(block, loop_header) : { |
| 3293 // if (block has already been visited or is of another loop) return; | 3279 // if (block has already been visited or is of another loop) return; |
| 3294 // mark block as visited; | 3280 // mark block as visited; |
| 3295 // if (block is a loop header) { | 3281 // if (block is a loop header) { |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3700 } | 3686 } |
| 3701 // Set this after possibly allocating a new TestContext above. | 3687 // Set this after possibly allocating a new TestContext above. |
| 3702 call_context_ = owner->ast_context(); | 3688 call_context_ = owner->ast_context(); |
| 3703 } | 3689 } |
| 3704 | 3690 |
| 3705 // Push on the state stack. | 3691 // Push on the state stack. |
| 3706 owner->set_function_state(this); | 3692 owner->set_function_state(this); |
| 3707 | 3693 |
| 3708 if (owner->is_tracking_positions()) { | 3694 if (owner->is_tracking_positions()) { |
| 3709 outer_source_position_ = owner->source_position(); | 3695 outer_source_position_ = owner->source_position(); |
| 3710 owner->EnterInlinedSource( | 3696 owner->EnterInlinedSource(inlining_id); |
| 3711 info->shared_info()->start_position(), | |
| 3712 inlining_id); | |
| 3713 owner->SetSourcePosition(info->shared_info()->start_position()); | 3697 owner->SetSourcePosition(info->shared_info()->start_position()); |
| 3714 } | 3698 } |
| 3715 } | 3699 } |
| 3716 | 3700 |
| 3717 | 3701 |
| 3718 FunctionState::~FunctionState() { | 3702 FunctionState::~FunctionState() { |
| 3719 delete test_context_; | 3703 delete test_context_; |
| 3720 owner_->set_function_state(outer_); | 3704 owner_->set_function_state(outer_); |
| 3721 | 3705 |
| 3722 if (owner_->is_tracking_positions()) { | 3706 if (owner_->is_tracking_positions()) { |
| 3723 owner_->set_source_position(outer_source_position_); | 3707 owner_->set_source_position(outer_source_position_); |
| 3724 owner_->EnterInlinedSource( | 3708 owner_->EnterInlinedSource(outer_->inlining_id()); |
| 3725 outer_->compilation_info()->shared_info()->start_position(), | |
| 3726 outer_->inlining_id()); | |
| 3727 } | 3709 } |
| 3728 } | 3710 } |
| 3729 | 3711 |
| 3730 | 3712 |
| 3731 // Implementation of utility classes to represent an expression's context in | 3713 // Implementation of utility classes to represent an expression's context in |
| 3732 // the AST. | 3714 // the AST. |
| 3733 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) | 3715 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
| 3734 : owner_(owner), | 3716 : owner_(owner), |
| 3735 kind_(kind), | 3717 kind_(kind), |
| 3736 outer_(owner->ast_context()), | 3718 outer_(owner->ast_context()), |
| (...skipping 4418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8155 // Generate the deoptimization data for the unoptimized version of | 8137 // Generate the deoptimization data for the unoptimized version of |
| 8156 // the target function if we don't already have it. | 8138 // the target function if we don't already have it. |
| 8157 if (!Compiler::EnsureDeoptimizationSupport(&target_info)) { | 8139 if (!Compiler::EnsureDeoptimizationSupport(&target_info)) { |
| 8158 TraceInline(target, caller, "could not generate deoptimization info"); | 8140 TraceInline(target, caller, "could not generate deoptimization info"); |
| 8159 return false; | 8141 return false; |
| 8160 } | 8142 } |
| 8161 | 8143 |
| 8162 // Remember that we inlined this function. This needs to be called right | 8144 // Remember that we inlined this function. This needs to be called right |
| 8163 // after the EnsureDeoptimizationSupport call so that the code flusher | 8145 // after the EnsureDeoptimizationSupport call so that the code flusher |
| 8164 // does not remove the code with the deoptimization support. | 8146 // does not remove the code with the deoptimization support. |
| 8165 top_info()->AddInlinedFunction(target_info.shared_info()); | 8147 int inlining_id = top_info()->AddInlinedFunction(target_info.shared_info(), |
| 8148 source_position()); |
| 8166 | 8149 |
| 8167 // ---------------------------------------------------------------- | 8150 // ---------------------------------------------------------------- |
| 8168 // After this point, we've made a decision to inline this function (so | 8151 // After this point, we've made a decision to inline this function (so |
| 8169 // TryInline should always return true). | 8152 // TryInline should always return true). |
| 8170 | 8153 |
| 8171 // If target was lazily compiled, it's literals array may not yet be set up. | 8154 // If target was lazily compiled, it's literals array may not yet be set up. |
| 8172 JSFunction::EnsureLiterals(target); | 8155 JSFunction::EnsureLiterals(target); |
| 8173 | 8156 |
| 8174 // Type-check the inlined function. | 8157 // Type-check the inlined function. |
| 8175 DCHECK(target_shared->has_deoptimization_support()); | 8158 DCHECK(target_shared->has_deoptimization_support()); |
| 8176 AstTyper(target_info.isolate(), target_info.zone(), target_info.closure(), | 8159 AstTyper(target_info.isolate(), target_info.zone(), target_info.closure(), |
| 8177 target_info.scope(), target_info.osr_ast_id(), target_info.literal(), | 8160 target_info.scope(), target_info.osr_ast_id(), target_info.literal(), |
| 8178 &bounds_) | 8161 &bounds_) |
| 8179 .Run(); | 8162 .Run(); |
| 8180 | 8163 |
| 8181 int inlining_id = 0; | |
| 8182 if (is_tracking_positions()) { | 8164 if (is_tracking_positions()) { |
| 8183 inlining_id = TraceInlinedFunction(target_shared, source_position()); | 8165 TraceInlinedFunction(target_shared, source_position(), inlining_id); |
| 8184 } | 8166 } |
| 8185 | 8167 |
| 8186 // Save the pending call context. Set up new one for the inlined function. | 8168 // Save the pending call context. Set up new one for the inlined function. |
| 8187 // The function state is new-allocated because we need to delete it | 8169 // The function state is new-allocated because we need to delete it |
| 8188 // in two different places. | 8170 // in two different places. |
| 8189 FunctionState* target_state = new FunctionState( | 8171 FunctionState* target_state = new FunctionState( |
| 8190 this, &target_info, inlining_kind, inlining_id, | 8172 this, &target_info, inlining_kind, inlining_id, |
| 8191 function_state()->ComputeTailCallMode(syntactic_tail_call_mode)); | 8173 function_state()->ComputeTailCallMode(syntactic_tail_call_mode)); |
| 8192 | 8174 |
| 8193 HConstant* undefined = graph()->GetConstantUndefined(); | 8175 HConstant* undefined = graph()->GetConstantUndefined(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 8224 current_block()->UpdateEnvironment(inner_env); | 8206 current_block()->UpdateEnvironment(inner_env); |
| 8225 Scope* saved_scope = scope(); | 8207 Scope* saved_scope = scope(); |
| 8226 set_scope(target_info.scope()); | 8208 set_scope(target_info.scope()); |
| 8227 HEnterInlined* enter_inlined = Add<HEnterInlined>( | 8209 HEnterInlined* enter_inlined = Add<HEnterInlined>( |
| 8228 return_id, target, context, arguments_count, function, | 8210 return_id, target, context, arguments_count, function, |
| 8229 function_state()->inlining_kind(), function->scope()->arguments(), | 8211 function_state()->inlining_kind(), function->scope()->arguments(), |
| 8230 arguments_object, syntactic_tail_call_mode); | 8212 arguments_object, syntactic_tail_call_mode); |
| 8231 if (is_tracking_positions()) { | 8213 if (is_tracking_positions()) { |
| 8232 enter_inlined->set_inlining_id(inlining_id); | 8214 enter_inlined->set_inlining_id(inlining_id); |
| 8233 } | 8215 } |
| 8216 |
| 8234 function_state()->set_entry(enter_inlined); | 8217 function_state()->set_entry(enter_inlined); |
| 8235 | 8218 |
| 8236 VisitDeclarations(target_info.scope()->declarations()); | 8219 VisitDeclarations(target_info.scope()->declarations()); |
| 8237 VisitStatements(function->body()); | 8220 VisitStatements(function->body()); |
| 8238 set_scope(saved_scope); | 8221 set_scope(saved_scope); |
| 8239 if (HasStackOverflow()) { | 8222 if (HasStackOverflow()) { |
| 8240 // Bail out if the inline function did, as we cannot residualize a call | 8223 // Bail out if the inline function did, as we cannot residualize a call |
| 8241 // instead, but do not disable optimization for the outer function. | 8224 // instead, but do not disable optimization for the outer function. |
| 8242 TraceInline(target, caller, "inline graph construction failed"); | 8225 TraceInline(target, caller, "inline graph construction failed"); |
| 8243 target_shared->DisableOptimization(kInliningBailedOut); | 8226 target_shared->DisableOptimization(kInliningBailedOut); |
| (...skipping 2885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11129 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 11112 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
| 11130 CHECK_ALIVE(VisitForValue(expr->left())); | 11113 CHECK_ALIVE(VisitForValue(expr->left())); |
| 11131 CHECK_ALIVE(VisitForValue(expr->right())); | 11114 CHECK_ALIVE(VisitForValue(expr->right())); |
| 11132 SetSourcePosition(expr->position()); | 11115 SetSourcePosition(expr->position()); |
| 11133 HValue* right = Pop(); | 11116 HValue* right = Pop(); |
| 11134 HValue* left = Pop(); | 11117 HValue* left = Pop(); |
| 11135 HValue* result = | 11118 HValue* result = |
| 11136 BuildBinaryOperation(expr, left, right, | 11119 BuildBinaryOperation(expr, left, right, |
| 11137 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE | 11120 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE |
| 11138 : PUSH_BEFORE_SIMULATE); | 11121 : PUSH_BEFORE_SIMULATE); |
| 11139 if (is_tracking_positions() && result->IsBinaryOperation()) { | |
| 11140 HBinaryOperation::cast(result)->SetOperandPositions( | |
| 11141 zone(), | |
| 11142 ScriptPositionToSourcePosition(expr->left()->position()), | |
| 11143 ScriptPositionToSourcePosition(expr->right()->position())); | |
| 11144 } | |
| 11145 return ast_context()->ReturnValue(result); | 11122 return ast_context()->ReturnValue(result); |
| 11146 } | 11123 } |
| 11147 | 11124 |
| 11148 | 11125 |
| 11149 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 11126 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
| 11150 Expression* sub_expr, | 11127 Expression* sub_expr, |
| 11151 Handle<String> check) { | 11128 Handle<String> check) { |
| 11152 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 11129 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
| 11153 SetSourcePosition(expr->position()); | 11130 SetSourcePosition(expr->position()); |
| 11154 HValue* value = Pop(); | 11131 HValue* value = Pop(); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11314 return New<HBranch>(graph()->GetConstantTrue()); | 11291 return New<HBranch>(graph()->GetConstantTrue()); |
| 11315 } | 11292 } |
| 11316 // Can we get away with map check and not instance type check? | 11293 // Can we get away with map check and not instance type check? |
| 11317 HValue* operand_to_check = | 11294 HValue* operand_to_check = |
| 11318 left->block()->block_id() < right->block()->block_id() ? left : right; | 11295 left->block()->block_id() < right->block()->block_id() ? left : right; |
| 11319 if (combined_type->IsClass()) { | 11296 if (combined_type->IsClass()) { |
| 11320 Handle<Map> map = combined_type->AsClass()->Map(); | 11297 Handle<Map> map = combined_type->AsClass()->Map(); |
| 11321 AddCheckMap(operand_to_check, map); | 11298 AddCheckMap(operand_to_check, map); |
| 11322 HCompareObjectEqAndBranch* result = | 11299 HCompareObjectEqAndBranch* result = |
| 11323 New<HCompareObjectEqAndBranch>(left, right); | 11300 New<HCompareObjectEqAndBranch>(left, right); |
| 11324 if (is_tracking_positions()) { | |
| 11325 result->set_operand_position(zone(), 0, left_position); | |
| 11326 result->set_operand_position(zone(), 1, right_position); | |
| 11327 } | |
| 11328 return result; | 11301 return result; |
| 11329 } else { | 11302 } else { |
| 11330 BuildCheckHeapObject(operand_to_check); | 11303 BuildCheckHeapObject(operand_to_check); |
| 11331 Add<HCheckInstanceType>(operand_to_check, | 11304 Add<HCheckInstanceType>(operand_to_check, |
| 11332 HCheckInstanceType::IS_JS_RECEIVER); | 11305 HCheckInstanceType::IS_JS_RECEIVER); |
| 11333 HCompareObjectEqAndBranch* result = | 11306 HCompareObjectEqAndBranch* result = |
| 11334 New<HCompareObjectEqAndBranch>(left, right); | 11307 New<HCompareObjectEqAndBranch>(left, right); |
| 11335 return result; | 11308 return result; |
| 11336 } | 11309 } |
| 11337 } else { | 11310 } else { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11457 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 11430 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
| 11458 } | 11431 } |
| 11459 } | 11432 } |
| 11460 // TODO(jkummerow): Can we make this more efficient? | 11433 // TODO(jkummerow): Can we make this more efficient? |
| 11461 HBranch* branch = New<HBranch>(result); | 11434 HBranch* branch = New<HBranch>(result); |
| 11462 return branch; | 11435 return branch; |
| 11463 } else { | 11436 } else { |
| 11464 HCompareNumericAndBranch* result = | 11437 HCompareNumericAndBranch* result = |
| 11465 New<HCompareNumericAndBranch>(left, right, op); | 11438 New<HCompareNumericAndBranch>(left, right, op); |
| 11466 result->set_observed_input_representation(left_rep, right_rep); | 11439 result->set_observed_input_representation(left_rep, right_rep); |
| 11467 if (is_tracking_positions()) { | |
| 11468 result->SetOperandPositions(zone(), left_position, right_position); | |
| 11469 } | |
| 11470 return result; | 11440 return result; |
| 11471 } | 11441 } |
| 11472 } | 11442 } |
| 11473 } | 11443 } |
| 11474 | 11444 |
| 11475 | 11445 |
| 11476 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 11446 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 11477 Expression* sub_expr, | 11447 Expression* sub_expr, |
| 11478 NilValue nil) { | 11448 NilValue nil) { |
| 11479 DCHECK(!HasStackOverflow()); | 11449 DCHECK(!HasStackOverflow()); |
| (...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12828 } | 12798 } |
| 12829 | 12799 |
| 12830 { | 12800 { |
| 12831 Tag HIR_tag(this, "HIR"); | 12801 Tag HIR_tag(this, "HIR"); |
| 12832 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { | 12802 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { |
| 12833 HInstruction* instruction = it.Current(); | 12803 HInstruction* instruction = it.Current(); |
| 12834 int uses = instruction->UseCount(); | 12804 int uses = instruction->UseCount(); |
| 12835 PrintIndent(); | 12805 PrintIndent(); |
| 12836 std::ostringstream os; | 12806 std::ostringstream os; |
| 12837 os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction; | 12807 os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction; |
| 12838 if (instruction->has_position() && instruction->position().raw() != 0) { | 12808 if (instruction->has_position()) { |
| 12839 const SourcePosition pos = instruction->position(); | 12809 const SourcePosition pos = instruction->position(); |
| 12840 os << " pos:"; | 12810 os << " pos:"; |
| 12841 if (pos.inlining_id() != 0) os << pos.inlining_id() << "_"; | 12811 if (pos.isInlined()) os << "inlining(" << pos.InliningId() << "),"; |
| 12842 os << pos.position(); | 12812 os << pos.ScriptOffset(); |
| 12843 } | 12813 } |
| 12844 os << " <|@\n"; | 12814 os << " <|@\n"; |
| 12845 trace_.Add(os.str().c_str()); | 12815 trace_.Add(os.str().c_str()); |
| 12846 } | 12816 } |
| 12847 } | 12817 } |
| 12848 | 12818 |
| 12849 | 12819 |
| 12850 if (chunk != NULL) { | 12820 if (chunk != NULL) { |
| 12851 Tag LIR_tag(this, "LIR"); | 12821 Tag LIR_tag(this, "LIR"); |
| 12852 int first_index = current->first_instruction_index(); | 12822 int first_index = current->first_instruction_index(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13039 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13009 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13040 } | 13010 } |
| 13041 | 13011 |
| 13042 #ifdef DEBUG | 13012 #ifdef DEBUG |
| 13043 graph_->Verify(false); // No full verify. | 13013 graph_->Verify(false); // No full verify. |
| 13044 #endif | 13014 #endif |
| 13045 } | 13015 } |
| 13046 | 13016 |
| 13047 } // namespace internal | 13017 } // namespace internal |
| 13048 } // namespace v8 | 13018 } // namespace v8 |
| OLD | NEW |