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 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1358 } | 1358 } |
1359 finished_ = true; | 1359 finished_ = true; |
1360 } | 1360 } |
1361 | 1361 |
1362 | 1362 |
1363 HGraph* HGraphBuilder::CreateGraph() { | 1363 HGraph* HGraphBuilder::CreateGraph() { |
1364 DCHECK(!FLAG_minimal); | 1364 DCHECK(!FLAG_minimal); |
1365 graph_ = new (zone()) HGraph(info_, descriptor_); | 1365 graph_ = new (zone()) HGraph(info_, descriptor_); |
1366 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); | 1366 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); |
1367 if (!info_->IsStub() && is_tracking_positions()) { | 1367 if (!info_->IsStub() && is_tracking_positions()) { |
1368 TraceInlinedFunction(info_->shared_info(), SourcePosition::Unknown()); | 1368 TraceInlinedFunction(info_->shared_info(), SourcePosition::Unknown(), -1); |
alph
2016/11/07 22:38:39
Is there a name for -1?
| |
1369 } | 1369 } |
1370 CompilationPhase phase("H_Block building", info_); | 1370 CompilationPhase phase("H_Block building", info_); |
1371 set_current_block(graph()->entry_block()); | 1371 set_current_block(graph()->entry_block()); |
1372 if (!BuildGraph()) return NULL; | 1372 if (!BuildGraph()) return NULL; |
1373 graph()->FinalizeUniqueness(); | 1373 graph()->FinalizeUniqueness(); |
1374 return graph_; | 1374 return graph_; |
1375 } | 1375 } |
1376 | 1376 |
1377 int HGraphBuilder::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 1377 void HGraphBuilder::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
1378 SourcePosition position) { | 1378 SourcePosition position, |
1379 int inlining_id) { | |
1379 DCHECK(is_tracking_positions()); | 1380 DCHECK(is_tracking_positions()); |
1380 | 1381 |
1381 int inline_id = static_cast<int>(graph()->inlined_function_infos().size()); | |
1382 HInlinedFunctionInfo info(shared->start_position()); | |
1383 if (!shared->script()->IsUndefined(isolate())) { | 1382 if (!shared->script()->IsUndefined(isolate())) { |
1384 Handle<Script> script(Script::cast(shared->script()), isolate()); | 1383 Handle<Script> script(Script::cast(shared->script()), isolate()); |
1385 | 1384 |
1386 if (FLAG_hydrogen_track_positions && | 1385 if (FLAG_hydrogen_track_positions && |
1387 !script->source()->IsUndefined(isolate())) { | 1386 !script->source()->IsUndefined(isolate())) { |
1388 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 1387 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
1389 Object* source_name = script->name(); | 1388 Object* source_name = script->name(); |
1390 OFStream os(tracing_scope.file()); | 1389 OFStream os(tracing_scope.file()); |
1391 os << "--- FUNCTION SOURCE ("; | 1390 os << "--- FUNCTION SOURCE ("; |
1392 if (source_name->IsString()) { | 1391 if (source_name->IsString()) { |
1393 os << String::cast(source_name)->ToCString().get() << ":"; | 1392 os << String::cast(source_name)->ToCString().get() << ":"; |
1394 } | 1393 } |
1395 os << shared->DebugName()->ToCString().get() << ") id{"; | 1394 os << shared->DebugName()->ToCString().get() << ") id{"; |
1396 os << info_->optimization_id() << "," << inline_id << "} ---\n"; | 1395 os << info_->optimization_id() << "," << inlining_id << "} ---\n"; |
1397 { | 1396 { |
1398 DisallowHeapAllocation no_allocation; | 1397 DisallowHeapAllocation no_allocation; |
1399 int start = shared->start_position(); | 1398 int start = shared->start_position(); |
1400 int len = shared->end_position() - start; | 1399 int len = shared->end_position() - start; |
1401 String::SubStringRange source(String::cast(script->source()), start, | 1400 String::SubStringRange source(String::cast(script->source()), start, |
1402 len); | 1401 len); |
1403 for (const auto& c : source) { | 1402 for (const auto& c : source) { |
1404 os << AsReversiblyEscapedUC16(c); | 1403 os << AsReversiblyEscapedUC16(c); |
1405 } | 1404 } |
1406 } | 1405 } |
1407 | 1406 |
1408 os << "\n--- END ---\n"; | 1407 os << "\n--- END ---\n"; |
1409 } | 1408 } |
1410 } | 1409 } |
1411 | 1410 |
1412 graph()->inlined_function_infos().push_back(info); | 1411 if (FLAG_hydrogen_track_positions && inlining_id != -1) { |
1413 | |
1414 if (FLAG_hydrogen_track_positions && inline_id != 0) { | |
1415 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 1412 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
1416 OFStream os(tracing_scope.file()); | 1413 OFStream os(tracing_scope.file()); |
1417 os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{" | 1414 os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{" |
1418 << info_->optimization_id() << "," << inline_id << "} AS " << inline_id | 1415 << info_->optimization_id() << "," << inlining_id << "} AS " |
1419 << " AT " << position << std::endl; | 1416 << inlining_id << " AT " << position.ScriptOffset() << std::endl; |
1420 } | 1417 } |
1421 | |
1422 return inline_id; | |
1423 } | 1418 } |
1424 | 1419 |
1425 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 1420 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
1426 DCHECK(current_block() != NULL); | 1421 DCHECK(current_block() != NULL); |
1427 DCHECK(!FLAG_hydrogen_track_positions || | 1422 DCHECK(!FLAG_hydrogen_track_positions || position_.IsKnown() || |
1428 !position_.IsUnknown() || | |
1429 !info_->IsOptimizing()); | 1423 !info_->IsOptimizing()); |
1430 current_block()->AddInstruction(instr, source_position()); | 1424 current_block()->AddInstruction(instr, source_position()); |
1431 if (graph()->IsInsideNoSideEffectsScope()) { | 1425 if (graph()->IsInsideNoSideEffectsScope()) { |
1432 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 1426 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
1433 } | 1427 } |
1434 return instr; | 1428 return instr; |
1435 } | 1429 } |
1436 | 1430 |
1437 | 1431 |
1438 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { | 1432 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { |
1439 DCHECK(!FLAG_hydrogen_track_positions || | 1433 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || |
1440 !info_->IsOptimizing() || | 1434 position_.IsKnown()); |
1441 !position_.IsUnknown()); | |
1442 current_block()->Finish(last, source_position()); | 1435 current_block()->Finish(last, source_position()); |
1443 if (last->IsReturn() || last->IsAbnormalExit()) { | 1436 if (last->IsReturn() || last->IsAbnormalExit()) { |
1444 set_current_block(NULL); | 1437 set_current_block(NULL); |
1445 } | 1438 } |
1446 } | 1439 } |
1447 | 1440 |
1448 | 1441 |
1449 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { | 1442 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { |
1450 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || | 1443 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || |
1451 !position_.IsUnknown()); | 1444 position_.IsKnown()); |
1452 current_block()->FinishExit(instruction, source_position()); | 1445 current_block()->FinishExit(instruction, source_position()); |
1453 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { | 1446 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { |
1454 set_current_block(NULL); | 1447 set_current_block(NULL); |
1455 } | 1448 } |
1456 } | 1449 } |
1457 | 1450 |
1458 | 1451 |
1459 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { | 1452 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { |
1460 if (FLAG_native_code_counters && counter->Enabled()) { | 1453 if (FLAG_native_code_counters && counter->Enabled()) { |
1461 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1454 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
(...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3120 HValue* HGraphBuilder::AddLoadJSBuiltin(int context_index) { | 3113 HValue* HGraphBuilder::AddLoadJSBuiltin(int context_index) { |
3121 HValue* native_context = BuildGetNativeContext(); | 3114 HValue* native_context = BuildGetNativeContext(); |
3122 HObjectAccess function_access = HObjectAccess::ForContextSlot(context_index); | 3115 HObjectAccess function_access = HObjectAccess::ForContextSlot(context_index); |
3123 return Add<HLoadNamedField>(native_context, nullptr, function_access); | 3116 return Add<HLoadNamedField>(native_context, nullptr, function_access); |
3124 } | 3117 } |
3125 | 3118 |
3126 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 3119 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
3127 bool track_positions) | 3120 bool track_positions) |
3128 : HGraphBuilder(info, CallInterfaceDescriptor(), track_positions), | 3121 : HGraphBuilder(info, CallInterfaceDescriptor(), track_positions), |
3129 function_state_(NULL), | 3122 function_state_(NULL), |
3130 initial_function_state_(this, info, NORMAL_RETURN, 0, | 3123 initial_function_state_(this, info, NORMAL_RETURN, -1, |
3131 TailCallMode::kAllow), | 3124 TailCallMode::kAllow), |
3132 ast_context_(NULL), | 3125 ast_context_(NULL), |
3133 break_scope_(NULL), | 3126 break_scope_(NULL), |
3134 inlined_count_(0), | 3127 inlined_count_(0), |
3135 globals_(10, info->zone()), | 3128 globals_(10, info->zone()), |
3136 osr_(new (info->zone()) HOsrBuilder(this)), | 3129 osr_(new (info->zone()) HOsrBuilder(this)), |
3137 bounds_(info->zone()) { | 3130 bounds_(info->zone()) { |
3138 // This is not initialized in the initializer list because the | 3131 // This is not initialized in the initializer list because the |
3139 // constructor for the initial state relies on function_state_ == NULL | 3132 // constructor for the initial state relies on function_state_ == NULL |
3140 // to know it's the initial state. | 3133 // to know it's the initial state. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3236 info_(info), | 3229 info_(info), |
3237 descriptor_(descriptor), | 3230 descriptor_(descriptor), |
3238 zone_(info->zone()), | 3231 zone_(info->zone()), |
3239 allow_code_motion_(false), | 3232 allow_code_motion_(false), |
3240 use_optimistic_licm_(false), | 3233 use_optimistic_licm_(false), |
3241 depends_on_empty_array_proto_elements_(false), | 3234 depends_on_empty_array_proto_elements_(false), |
3242 depends_on_string_length_overflow_(false), | 3235 depends_on_string_length_overflow_(false), |
3243 type_change_checksum_(0), | 3236 type_change_checksum_(0), |
3244 maximum_environment_size_(0), | 3237 maximum_environment_size_(0), |
3245 no_side_effects_scope_count_(0), | 3238 no_side_effects_scope_count_(0), |
3246 disallow_adding_new_values_(false), | 3239 disallow_adding_new_values_(false) { |
3247 inlined_function_infos_(info->zone()) { | |
3248 if (info->IsStub()) { | 3240 if (info->IsStub()) { |
3249 // For stubs, explicitly add the context to the environment. | 3241 // For stubs, explicitly add the context to the environment. |
3250 start_environment_ = | 3242 start_environment_ = |
3251 new (zone_) HEnvironment(zone_, descriptor.GetParameterCount() + 1); | 3243 new (zone_) HEnvironment(zone_, descriptor.GetParameterCount() + 1); |
3252 } else { | 3244 } else { |
3253 start_environment_ = | 3245 start_environment_ = |
3254 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 3246 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
3255 } | 3247 } |
3256 start_environment_->set_ast_id(BailoutId::FunctionContext()); | 3248 start_environment_->set_ast_id(BailoutId::FunctionContext()); |
3257 entry_block_ = CreateBasicBlock(); | 3249 entry_block_ = CreateBasicBlock(); |
(...skipping 11 matching lines...) Expand all Loading... | |
3269 void HGraph::FinalizeUniqueness() { | 3261 void HGraph::FinalizeUniqueness() { |
3270 DisallowHeapAllocation no_gc; | 3262 DisallowHeapAllocation no_gc; |
3271 for (int i = 0; i < blocks()->length(); ++i) { | 3263 for (int i = 0; i < blocks()->length(); ++i) { |
3272 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { | 3264 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
3273 it.Current()->FinalizeUniqueness(); | 3265 it.Current()->FinalizeUniqueness(); |
3274 } | 3266 } |
3275 } | 3267 } |
3276 } | 3268 } |
3277 | 3269 |
3278 | 3270 |
3279 int HGraph::SourcePositionToScriptPosition(SourcePosition pos) { | |
3280 return (FLAG_hydrogen_track_positions && !pos.IsUnknown()) | |
3281 ? inlined_function_infos_.at(pos.inlining_id()).start_position + | |
3282 pos.position() | |
3283 : pos.raw(); | |
3284 } | |
3285 | |
3286 | |
3287 // Block ordering was implemented with two mutually recursive methods, | 3271 // Block ordering was implemented with two mutually recursive methods, |
3288 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 3272 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
3289 // The recursion could lead to stack overflow so the algorithm has been | 3273 // The recursion could lead to stack overflow so the algorithm has been |
3290 // implemented iteratively. | 3274 // implemented iteratively. |
3291 // At a high level the algorithm looks like this: | 3275 // At a high level the algorithm looks like this: |
3292 // | 3276 // |
3293 // Postorder(block, loop_header) : { | 3277 // Postorder(block, loop_header) : { |
3294 // if (block has already been visited or is of another loop) return; | 3278 // if (block has already been visited or is of another loop) return; |
3295 // mark block as visited; | 3279 // mark block as visited; |
3296 // if (block is a loop header) { | 3280 // if (block is a loop header) { |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3701 } | 3685 } |
3702 // Set this after possibly allocating a new TestContext above. | 3686 // Set this after possibly allocating a new TestContext above. |
3703 call_context_ = owner->ast_context(); | 3687 call_context_ = owner->ast_context(); |
3704 } | 3688 } |
3705 | 3689 |
3706 // Push on the state stack. | 3690 // Push on the state stack. |
3707 owner->set_function_state(this); | 3691 owner->set_function_state(this); |
3708 | 3692 |
3709 if (owner->is_tracking_positions()) { | 3693 if (owner->is_tracking_positions()) { |
3710 outer_source_position_ = owner->source_position(); | 3694 outer_source_position_ = owner->source_position(); |
3711 owner->EnterInlinedSource( | 3695 owner->EnterInlinedSource(inlining_id); |
3712 info->shared_info()->start_position(), | |
3713 inlining_id); | |
3714 owner->SetSourcePosition(info->shared_info()->start_position()); | 3696 owner->SetSourcePosition(info->shared_info()->start_position()); |
3715 } | 3697 } |
3716 } | 3698 } |
3717 | 3699 |
3718 | 3700 |
3719 FunctionState::~FunctionState() { | 3701 FunctionState::~FunctionState() { |
3720 delete test_context_; | 3702 delete test_context_; |
3721 owner_->set_function_state(outer_); | 3703 owner_->set_function_state(outer_); |
3722 | 3704 |
3723 if (owner_->is_tracking_positions()) { | 3705 if (owner_->is_tracking_positions()) { |
3724 owner_->set_source_position(outer_source_position_); | 3706 owner_->set_source_position(outer_source_position_); |
3725 owner_->EnterInlinedSource( | 3707 owner_->EnterInlinedSource(outer_->inlining_id()); |
3726 outer_->compilation_info()->shared_info()->start_position(), | |
3727 outer_->inlining_id()); | |
3728 } | 3708 } |
3729 } | 3709 } |
3730 | 3710 |
3731 | 3711 |
3732 // Implementation of utility classes to represent an expression's context in | 3712 // Implementation of utility classes to represent an expression's context in |
3733 // the AST. | 3713 // the AST. |
3734 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) | 3714 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
3735 : owner_(owner), | 3715 : owner_(owner), |
3736 kind_(kind), | 3716 kind_(kind), |
3737 outer_(owner->ast_context()), | 3717 outer_(owner->ast_context()), |
(...skipping 4391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8129 // Generate the deoptimization data for the unoptimized version of | 8109 // Generate the deoptimization data for the unoptimized version of |
8130 // the target function if we don't already have it. | 8110 // the target function if we don't already have it. |
8131 if (!Compiler::EnsureDeoptimizationSupport(&target_info)) { | 8111 if (!Compiler::EnsureDeoptimizationSupport(&target_info)) { |
8132 TraceInline(target, caller, "could not generate deoptimization info"); | 8112 TraceInline(target, caller, "could not generate deoptimization info"); |
8133 return false; | 8113 return false; |
8134 } | 8114 } |
8135 | 8115 |
8136 // Remember that we inlined this function. This needs to be called right | 8116 // Remember that we inlined this function. This needs to be called right |
8137 // after the EnsureDeoptimizationSupport call so that the code flusher | 8117 // after the EnsureDeoptimizationSupport call so that the code flusher |
8138 // does not remove the code with the deoptimization support. | 8118 // does not remove the code with the deoptimization support. |
8139 top_info()->AddInlinedFunction(target_info.shared_info()); | 8119 int inlining_id = top_info()->AddInlinedFunction(target_info.shared_info(), |
8120 source_position()); | |
8140 | 8121 |
8141 // ---------------------------------------------------------------- | 8122 // ---------------------------------------------------------------- |
8142 // After this point, we've made a decision to inline this function (so | 8123 // After this point, we've made a decision to inline this function (so |
8143 // TryInline should always return true). | 8124 // TryInline should always return true). |
8144 | 8125 |
8145 // If target was lazily compiled, it's literals array may not yet be set up. | 8126 // If target was lazily compiled, it's literals array may not yet be set up. |
8146 JSFunction::EnsureLiterals(target); | 8127 JSFunction::EnsureLiterals(target); |
8147 | 8128 |
8148 // Type-check the inlined function. | 8129 // Type-check the inlined function. |
8149 DCHECK(target_shared->has_deoptimization_support()); | 8130 DCHECK(target_shared->has_deoptimization_support()); |
8150 AstTyper(target_info.isolate(), target_info.zone(), target_info.closure(), | 8131 AstTyper(target_info.isolate(), target_info.zone(), target_info.closure(), |
8151 target_info.scope(), target_info.osr_ast_id(), target_info.literal(), | 8132 target_info.scope(), target_info.osr_ast_id(), target_info.literal(), |
8152 &bounds_) | 8133 &bounds_) |
8153 .Run(); | 8134 .Run(); |
8154 | 8135 |
8155 int inlining_id = 0; | |
8156 if (is_tracking_positions()) { | 8136 if (is_tracking_positions()) { |
8157 inlining_id = TraceInlinedFunction(target_shared, source_position()); | 8137 TraceInlinedFunction(target_shared, source_position(), inlining_id); |
8158 } | 8138 } |
8159 | 8139 |
8160 // Save the pending call context. Set up new one for the inlined function. | 8140 // Save the pending call context. Set up new one for the inlined function. |
8161 // The function state is new-allocated because we need to delete it | 8141 // The function state is new-allocated because we need to delete it |
8162 // in two different places. | 8142 // in two different places. |
8163 FunctionState* target_state = new FunctionState( | 8143 FunctionState* target_state = new FunctionState( |
8164 this, &target_info, inlining_kind, inlining_id, | 8144 this, &target_info, inlining_kind, inlining_id, |
8165 function_state()->ComputeTailCallMode(syntactic_tail_call_mode)); | 8145 function_state()->ComputeTailCallMode(syntactic_tail_call_mode)); |
8166 | 8146 |
8167 HConstant* undefined = graph()->GetConstantUndefined(); | 8147 HConstant* undefined = graph()->GetConstantUndefined(); |
(...skipping 30 matching lines...) Expand all Loading... | |
8198 current_block()->UpdateEnvironment(inner_env); | 8178 current_block()->UpdateEnvironment(inner_env); |
8199 Scope* saved_scope = scope(); | 8179 Scope* saved_scope = scope(); |
8200 set_scope(target_info.scope()); | 8180 set_scope(target_info.scope()); |
8201 HEnterInlined* enter_inlined = Add<HEnterInlined>( | 8181 HEnterInlined* enter_inlined = Add<HEnterInlined>( |
8202 return_id, target, context, arguments_count, function, | 8182 return_id, target, context, arguments_count, function, |
8203 function_state()->inlining_kind(), function->scope()->arguments(), | 8183 function_state()->inlining_kind(), function->scope()->arguments(), |
8204 arguments_object, syntactic_tail_call_mode); | 8184 arguments_object, syntactic_tail_call_mode); |
8205 if (is_tracking_positions()) { | 8185 if (is_tracking_positions()) { |
8206 enter_inlined->set_inlining_id(inlining_id); | 8186 enter_inlined->set_inlining_id(inlining_id); |
8207 } | 8187 } |
8188 | |
8208 function_state()->set_entry(enter_inlined); | 8189 function_state()->set_entry(enter_inlined); |
8209 | 8190 |
8210 VisitDeclarations(target_info.scope()->declarations()); | 8191 VisitDeclarations(target_info.scope()->declarations()); |
8211 VisitStatements(function->body()); | 8192 VisitStatements(function->body()); |
8212 set_scope(saved_scope); | 8193 set_scope(saved_scope); |
8213 if (HasStackOverflow()) { | 8194 if (HasStackOverflow()) { |
8214 // Bail out if the inline function did, as we cannot residualize a call | 8195 // Bail out if the inline function did, as we cannot residualize a call |
8215 // instead, but do not disable optimization for the outer function. | 8196 // instead, but do not disable optimization for the outer function. |
8216 TraceInline(target, caller, "inline graph construction failed"); | 8197 TraceInline(target, caller, "inline graph construction failed"); |
8217 target_shared->DisableOptimization(kInliningBailedOut); | 8198 target_shared->DisableOptimization(kInliningBailedOut); |
(...skipping 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11123 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 11104 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
11124 CHECK_ALIVE(VisitForValue(expr->left())); | 11105 CHECK_ALIVE(VisitForValue(expr->left())); |
11125 CHECK_ALIVE(VisitForValue(expr->right())); | 11106 CHECK_ALIVE(VisitForValue(expr->right())); |
11126 SetSourcePosition(expr->position()); | 11107 SetSourcePosition(expr->position()); |
11127 HValue* right = Pop(); | 11108 HValue* right = Pop(); |
11128 HValue* left = Pop(); | 11109 HValue* left = Pop(); |
11129 HValue* result = | 11110 HValue* result = |
11130 BuildBinaryOperation(expr, left, right, | 11111 BuildBinaryOperation(expr, left, right, |
11131 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE | 11112 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE |
11132 : PUSH_BEFORE_SIMULATE); | 11113 : PUSH_BEFORE_SIMULATE); |
11133 if (is_tracking_positions() && result->IsBinaryOperation()) { | |
11134 HBinaryOperation::cast(result)->SetOperandPositions( | |
11135 zone(), | |
11136 ScriptPositionToSourcePosition(expr->left()->position()), | |
11137 ScriptPositionToSourcePosition(expr->right()->position())); | |
11138 } | |
11139 return ast_context()->ReturnValue(result); | 11114 return ast_context()->ReturnValue(result); |
11140 } | 11115 } |
11141 | 11116 |
11142 | 11117 |
11143 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 11118 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
11144 Expression* sub_expr, | 11119 Expression* sub_expr, |
11145 Handle<String> check) { | 11120 Handle<String> check) { |
11146 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 11121 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
11147 SetSourcePosition(expr->position()); | 11122 SetSourcePosition(expr->position()); |
11148 HValue* value = Pop(); | 11123 HValue* value = Pop(); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11308 return New<HBranch>(graph()->GetConstantTrue()); | 11283 return New<HBranch>(graph()->GetConstantTrue()); |
11309 } | 11284 } |
11310 // Can we get away with map check and not instance type check? | 11285 // Can we get away with map check and not instance type check? |
11311 HValue* operand_to_check = | 11286 HValue* operand_to_check = |
11312 left->block()->block_id() < right->block()->block_id() ? left : right; | 11287 left->block()->block_id() < right->block()->block_id() ? left : right; |
11313 if (combined_type->IsClass()) { | 11288 if (combined_type->IsClass()) { |
11314 Handle<Map> map = combined_type->AsClass()->Map(); | 11289 Handle<Map> map = combined_type->AsClass()->Map(); |
11315 AddCheckMap(operand_to_check, map); | 11290 AddCheckMap(operand_to_check, map); |
11316 HCompareObjectEqAndBranch* result = | 11291 HCompareObjectEqAndBranch* result = |
11317 New<HCompareObjectEqAndBranch>(left, right); | 11292 New<HCompareObjectEqAndBranch>(left, right); |
11318 if (is_tracking_positions()) { | |
11319 result->set_operand_position(zone(), 0, left_position); | |
11320 result->set_operand_position(zone(), 1, right_position); | |
11321 } | |
11322 return result; | 11293 return result; |
11323 } else { | 11294 } else { |
11324 BuildCheckHeapObject(operand_to_check); | 11295 BuildCheckHeapObject(operand_to_check); |
11325 Add<HCheckInstanceType>(operand_to_check, | 11296 Add<HCheckInstanceType>(operand_to_check, |
11326 HCheckInstanceType::IS_JS_RECEIVER); | 11297 HCheckInstanceType::IS_JS_RECEIVER); |
11327 HCompareObjectEqAndBranch* result = | 11298 HCompareObjectEqAndBranch* result = |
11328 New<HCompareObjectEqAndBranch>(left, right); | 11299 New<HCompareObjectEqAndBranch>(left, right); |
11329 return result; | 11300 return result; |
11330 } | 11301 } |
11331 } else { | 11302 } else { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11451 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 11422 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
11452 } | 11423 } |
11453 } | 11424 } |
11454 // TODO(jkummerow): Can we make this more efficient? | 11425 // TODO(jkummerow): Can we make this more efficient? |
11455 HBranch* branch = New<HBranch>(result); | 11426 HBranch* branch = New<HBranch>(result); |
11456 return branch; | 11427 return branch; |
11457 } else { | 11428 } else { |
11458 HCompareNumericAndBranch* result = | 11429 HCompareNumericAndBranch* result = |
11459 New<HCompareNumericAndBranch>(left, right, op); | 11430 New<HCompareNumericAndBranch>(left, right, op); |
11460 result->set_observed_input_representation(left_rep, right_rep); | 11431 result->set_observed_input_representation(left_rep, right_rep); |
11461 if (is_tracking_positions()) { | |
11462 result->SetOperandPositions(zone(), left_position, right_position); | |
11463 } | |
11464 return result; | 11432 return result; |
11465 } | 11433 } |
11466 } | 11434 } |
11467 } | 11435 } |
11468 | 11436 |
11469 | 11437 |
11470 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 11438 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
11471 Expression* sub_expr, | 11439 Expression* sub_expr, |
11472 NilValue nil) { | 11440 NilValue nil) { |
11473 DCHECK(!HasStackOverflow()); | 11441 DCHECK(!HasStackOverflow()); |
(...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12822 } | 12790 } |
12823 | 12791 |
12824 { | 12792 { |
12825 Tag HIR_tag(this, "HIR"); | 12793 Tag HIR_tag(this, "HIR"); |
12826 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { | 12794 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { |
12827 HInstruction* instruction = it.Current(); | 12795 HInstruction* instruction = it.Current(); |
12828 int uses = instruction->UseCount(); | 12796 int uses = instruction->UseCount(); |
12829 PrintIndent(); | 12797 PrintIndent(); |
12830 std::ostringstream os; | 12798 std::ostringstream os; |
12831 os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction; | 12799 os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction; |
12832 if (instruction->has_position() && instruction->position().raw() != 0) { | 12800 if (instruction->has_position()) { |
12833 const SourcePosition pos = instruction->position(); | 12801 const SourcePosition pos = instruction->position(); |
12834 os << " pos:"; | 12802 os << " pos:"; |
12835 if (pos.inlining_id() != 0) os << pos.inlining_id() << "_"; | 12803 if (pos.isInlined()) os << "inlining(" << pos.InliningId() << "),"; |
12836 os << pos.position(); | 12804 os << pos.ScriptOffset(); |
12837 } | 12805 } |
12838 os << " <|@\n"; | 12806 os << " <|@\n"; |
12839 trace_.Add(os.str().c_str()); | 12807 trace_.Add(os.str().c_str()); |
12840 } | 12808 } |
12841 } | 12809 } |
12842 | 12810 |
12843 | 12811 |
12844 if (chunk != NULL) { | 12812 if (chunk != NULL) { |
12845 Tag LIR_tag(this, "LIR"); | 12813 Tag LIR_tag(this, "LIR"); |
12846 int first_index = current->first_instruction_index(); | 12814 int first_index = current->first_instruction_index(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13033 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13001 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13034 } | 13002 } |
13035 | 13003 |
13036 #ifdef DEBUG | 13004 #ifdef DEBUG |
13037 graph_->Verify(false); // No full verify. | 13005 graph_->Verify(false); // No full verify. |
13038 #endif | 13006 #endif |
13039 } | 13007 } |
13040 | 13008 |
13041 } // namespace internal | 13009 } // namespace internal |
13042 } // namespace v8 | 13010 } // namespace v8 |
OLD | NEW |