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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 3432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3443 uint32_instructions_(NULL), | 3443 uint32_instructions_(NULL), |
3444 osr_(NULL), | 3444 osr_(NULL), |
3445 info_(info), | 3445 info_(info), |
3446 zone_(info->zone()), | 3446 zone_(info->zone()), |
3447 is_recursive_(false), | 3447 is_recursive_(false), |
3448 use_optimistic_licm_(false), | 3448 use_optimistic_licm_(false), |
3449 depends_on_empty_array_proto_elements_(false), | 3449 depends_on_empty_array_proto_elements_(false), |
3450 type_change_checksum_(0), | 3450 type_change_checksum_(0), |
3451 maximum_environment_size_(0), | 3451 maximum_environment_size_(0), |
3452 no_side_effects_scope_count_(0), | 3452 no_side_effects_scope_count_(0), |
3453 disallow_adding_new_values_(false), | 3453 disallow_adding_new_values_(false) { |
3454 inlined_functions_(FLAG_hydrogen_track_positions ? 5 : 0, info->zone()), | |
3455 inlining_id_to_function_id_(FLAG_hydrogen_track_positions ? 5 : 0, | |
3456 info->zone()) { | |
3457 if (info->IsStub()) { | 3454 if (info->IsStub()) { |
3458 CallInterfaceDescriptor descriptor = | 3455 CallInterfaceDescriptor descriptor = |
3459 info->code_stub()->GetCallInterfaceDescriptor(); | 3456 info->code_stub()->GetCallInterfaceDescriptor(); |
3460 start_environment_ = new (zone_) | 3457 start_environment_ = new (zone_) |
3461 HEnvironment(zone_, descriptor.GetEnvironmentParameterCount()); | 3458 HEnvironment(zone_, descriptor.GetEnvironmentParameterCount()); |
3462 } else { | 3459 } else { |
3463 TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown()); | 3460 info->TraceInlinedFunction(info->shared_info(), |
| 3461 HSourcePosition::Unknown().raw()); |
3464 start_environment_ = | 3462 start_environment_ = |
3465 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 3463 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
3466 } | 3464 } |
3467 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | 3465 start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
3468 entry_block_ = CreateBasicBlock(); | 3466 entry_block_ = CreateBasicBlock(); |
3469 entry_block_->SetInitialEnvironment(start_environment_); | 3467 entry_block_->SetInitialEnvironment(start_environment_); |
3470 } | 3468 } |
3471 | 3469 |
3472 | 3470 |
3473 HBasicBlock* HGraph::CreateBasicBlock() { | 3471 HBasicBlock* HGraph::CreateBasicBlock() { |
3474 HBasicBlock* result = new(zone()) HBasicBlock(this); | 3472 HBasicBlock* result = new(zone()) HBasicBlock(this); |
3475 blocks_.Add(result, zone()); | 3473 blocks_.Add(result, zone()); |
3476 return result; | 3474 return result; |
3477 } | 3475 } |
3478 | 3476 |
3479 | 3477 |
3480 void HGraph::FinalizeUniqueness() { | 3478 void HGraph::FinalizeUniqueness() { |
3481 DisallowHeapAllocation no_gc; | 3479 DisallowHeapAllocation no_gc; |
3482 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 3480 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
3483 for (int i = 0; i < blocks()->length(); ++i) { | 3481 for (int i = 0; i < blocks()->length(); ++i) { |
3484 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { | 3482 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
3485 it.Current()->FinalizeUniqueness(); | 3483 it.Current()->FinalizeUniqueness(); |
3486 } | 3484 } |
3487 } | 3485 } |
3488 } | 3486 } |
3489 | 3487 |
3490 | 3488 |
3491 int HGraph::TraceInlinedFunction( | |
3492 Handle<SharedFunctionInfo> shared, | |
3493 HSourcePosition position) { | |
3494 if (!FLAG_hydrogen_track_positions) { | |
3495 return 0; | |
3496 } | |
3497 | |
3498 int id = 0; | |
3499 for (; id < inlined_functions_.length(); id++) { | |
3500 if (inlined_functions_[id].shared().is_identical_to(shared)) { | |
3501 break; | |
3502 } | |
3503 } | |
3504 | |
3505 if (id == inlined_functions_.length()) { | |
3506 inlined_functions_.Add(InlinedFunctionInfo(shared), zone()); | |
3507 | |
3508 if (!shared->script()->IsUndefined()) { | |
3509 Handle<Script> script(Script::cast(shared->script())); | |
3510 if (!script->source()->IsUndefined()) { | |
3511 CodeTracer::Scope tracing_scopex(isolate()->GetCodeTracer()); | |
3512 OFStream os(tracing_scopex.file()); | |
3513 os << "--- FUNCTION SOURCE (" << shared->DebugName()->ToCString().get() | |
3514 << ") id{" << info()->optimization_id() << "," << id << "} ---\n"; | |
3515 { | |
3516 DisallowHeapAllocation no_allocation; | |
3517 int start = shared->start_position(); | |
3518 int len = shared->end_position() - start + 1; | |
3519 String::SubStringRange source(String::cast(script->source()), start, | |
3520 len); | |
3521 for (const auto& c : source) { | |
3522 os << AsReversiblyEscapedUC16(c); | |
3523 } | |
3524 } | |
3525 | |
3526 os << "\n--- END ---\n"; | |
3527 } | |
3528 } | |
3529 } | |
3530 | |
3531 int inline_id = inlining_id_to_function_id_.length(); | |
3532 inlining_id_to_function_id_.Add(id, zone()); | |
3533 | |
3534 if (inline_id != 0) { | |
3535 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | |
3536 OFStream os(tracing_scope.file()); | |
3537 os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{" | |
3538 << info()->optimization_id() << "," << id << "} AS " << inline_id | |
3539 << " AT " << position << std::endl; | |
3540 } | |
3541 | |
3542 return inline_id; | |
3543 } | |
3544 | |
3545 | |
3546 int HGraph::SourcePositionToScriptPosition(HSourcePosition pos) { | 3489 int HGraph::SourcePositionToScriptPosition(HSourcePosition pos) { |
3547 if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) { | 3490 if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) { |
3548 return pos.raw(); | 3491 return pos.raw(); |
3549 } | 3492 } |
3550 | 3493 |
3551 const int id = inlining_id_to_function_id_[pos.inlining_id()]; | 3494 const int id = info()->inlining_id_to_function_id()->at(pos.inlining_id()); |
3552 return inlined_functions_[id].start_position() + pos.position(); | 3495 return info()->inlined_function_infos()->at(id).start_position() + |
| 3496 pos.position(); |
3553 } | 3497 } |
3554 | 3498 |
3555 | 3499 |
3556 // Block ordering was implemented with two mutually recursive methods, | 3500 // Block ordering was implemented with two mutually recursive methods, |
3557 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 3501 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
3558 // The recursion could lead to stack overflow so the algorithm has been | 3502 // The recursion could lead to stack overflow so the algorithm has been |
3559 // implemented iteratively. | 3503 // implemented iteratively. |
3560 // At a high level the algorithm looks like this: | 3504 // At a high level the algorithm looks like this: |
3561 // | 3505 // |
3562 // Postorder(block, loop_header) : { | 3506 // Postorder(block, loop_header) : { |
(...skipping 4417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7980 } | 7924 } |
7981 | 7925 |
7982 // ---------------------------------------------------------------- | 7926 // ---------------------------------------------------------------- |
7983 // After this point, we've made a decision to inline this function (so | 7927 // After this point, we've made a decision to inline this function (so |
7984 // TryInline should always return true). | 7928 // TryInline should always return true). |
7985 | 7929 |
7986 // Type-check the inlined function. | 7930 // Type-check the inlined function. |
7987 DCHECK(target_shared->has_deoptimization_support()); | 7931 DCHECK(target_shared->has_deoptimization_support()); |
7988 AstTyper::Run(&target_info); | 7932 AstTyper::Run(&target_info); |
7989 | 7933 |
7990 int function_id = graph()->TraceInlinedFunction(target_shared, position); | 7934 int function_id = |
| 7935 top_info()->TraceInlinedFunction(target_shared, position.raw()); |
7991 | 7936 |
7992 // Save the pending call context. Set up new one for the inlined function. | 7937 // Save the pending call context. Set up new one for the inlined function. |
7993 // The function state is new-allocated because we need to delete it | 7938 // The function state is new-allocated because we need to delete it |
7994 // in two different places. | 7939 // in two different places. |
7995 FunctionState* target_state = new FunctionState( | 7940 FunctionState* target_state = new FunctionState( |
7996 this, &target_info, inlining_kind, function_id); | 7941 this, &target_info, inlining_kind, function_id); |
7997 | 7942 |
7998 HConstant* undefined = graph()->GetConstantUndefined(); | 7943 HConstant* undefined = graph()->GetConstantUndefined(); |
7999 | 7944 |
8000 HEnvironment* inner_env = | 7945 HEnvironment* inner_env = |
(...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9214 if (!prop->key()->IsPropertyName()) { | 9159 if (!prop->key()->IsPropertyName()) { |
9215 CHECK_ALIVE(VisitForValue(prop->key())); | 9160 CHECK_ALIVE(VisitForValue(prop->key())); |
9216 key = Pop(); | 9161 key = Pop(); |
9217 } | 9162 } |
9218 | 9163 |
9219 CHECK_ALIVE(PushLoad(prop, receiver, key)); | 9164 CHECK_ALIVE(PushLoad(prop, receiver, key)); |
9220 HValue* function = Pop(); | 9165 HValue* function = Pop(); |
9221 | 9166 |
9222 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); | 9167 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
9223 | 9168 |
9224 | |
9225 | |
9226 if (function->IsConstant() && | 9169 if (function->IsConstant() && |
9227 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 9170 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
9228 // Push the function under the receiver. | 9171 // Push the function under the receiver. |
9229 environment()->SetExpressionStackAt(0, function); | 9172 environment()->SetExpressionStackAt(0, function); |
9230 Push(receiver); | 9173 Push(receiver); |
9231 | 9174 |
9232 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 9175 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
9233 HConstant::cast(function)->handle(isolate())); | 9176 HConstant::cast(function)->handle(isolate())); |
9234 expr->set_target(known_function); | 9177 expr->set_target(known_function); |
9235 | 9178 |
(...skipping 4278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13514 if (ShouldProduceTraceOutput()) { | 13457 if (ShouldProduceTraceOutput()) { |
13515 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13458 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13516 } | 13459 } |
13517 | 13460 |
13518 #ifdef DEBUG | 13461 #ifdef DEBUG |
13519 graph_->Verify(false); // No full verify. | 13462 graph_->Verify(false); // No full verify. |
13520 #endif | 13463 #endif |
13521 } | 13464 } |
13522 | 13465 |
13523 } } // namespace v8::internal | 13466 } } // namespace v8::internal |
OLD | NEW |