| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 | 498 |
| 499 int visited_count_; | 499 int visited_count_; |
| 500 ZoneList<HBasicBlock*> stack_; | 500 ZoneList<HBasicBlock*> stack_; |
| 501 BitVector reachable_; | 501 BitVector reachable_; |
| 502 HBasicBlock* dont_visit_; | 502 HBasicBlock* dont_visit_; |
| 503 }; | 503 }; |
| 504 | 504 |
| 505 | 505 |
| 506 void HGraph::Verify(bool do_full_verify) const { | 506 void HGraph::Verify(bool do_full_verify) const { |
| 507 // Allow dereferencing for debug mode verification. | 507 // Allow dereferencing for debug mode verification. |
| 508 AllowHandleDereference allow_handle_deref(isolate()); | 508 Heap::RelocationLock(isolate()->heap()); |
| 509 HandleDereferenceGuard allow_handle_deref(isolate(), |
| 510 HandleDereferenceGuard::ALLOW); |
| 509 for (int i = 0; i < blocks_.length(); i++) { | 511 for (int i = 0; i < blocks_.length(); i++) { |
| 510 HBasicBlock* block = blocks_.at(i); | 512 HBasicBlock* block = blocks_.at(i); |
| 511 | 513 |
| 512 block->Verify(); | 514 block->Verify(); |
| 513 | 515 |
| 514 // Check that every block contains at least one node and that only the last | 516 // Check that every block contains at least one node and that only the last |
| 515 // node is a control instruction. | 517 // node is a control instruction. |
| 516 HInstruction* current = block->first(); | 518 HInstruction* current = block->first(); |
| 517 ASSERT(current != NULL && current->IsBlockEntry()); | 519 ASSERT(current != NULL && current->IsBlockEntry()); |
| 518 while (current != NULL) { | 520 while (current != NULL) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 block->dominator()); | 580 block->dominator()); |
| 579 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); | 581 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); |
| 580 } | 582 } |
| 581 } | 583 } |
| 582 } | 584 } |
| 583 } | 585 } |
| 584 | 586 |
| 585 #endif | 587 #endif |
| 586 | 588 |
| 587 | 589 |
| 588 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, | |
| 589 Handle<Object> value) { | |
| 590 if (!pointer->is_set()) { | |
| 591 HConstant* constant = new(zone()) HConstant(value, | |
| 592 Representation::Tagged()); | |
| 593 constant->InsertAfter(GetConstantUndefined()); | |
| 594 pointer->set(constant); | |
| 595 } | |
| 596 return pointer->get(); | |
| 597 } | |
| 598 | |
| 599 | |
| 600 HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer, | 590 HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer, |
| 601 int32_t value) { | 591 int32_t value) { |
| 602 if (!pointer->is_set()) { | 592 if (!pointer->is_set()) { |
| 603 HConstant* constant = | 593 HConstant* constant = |
| 604 new(zone()) HConstant(value, Representation::Integer32()); | 594 new(zone()) HConstant(value, Representation::Integer32()); |
| 605 constant->InsertAfter(GetConstantUndefined()); | 595 constant->InsertAfter(GetConstantUndefined()); |
| 606 pointer->set(constant); | 596 pointer->set(constant); |
| 607 } | 597 } |
| 608 return pointer->get(); | 598 return pointer->get(); |
| 609 } | 599 } |
| 610 | 600 |
| 611 | 601 |
| 612 HConstant* HGraph::GetConstant0() { | 602 HConstant* HGraph::GetConstant0() { |
| 613 return GetConstantInt32(&constant_0_, 0); | 603 return GetConstantInt32(&constant_0_, 0); |
| 614 } | 604 } |
| 615 | 605 |
| 616 | 606 |
| 617 HConstant* HGraph::GetConstant1() { | 607 HConstant* HGraph::GetConstant1() { |
| 618 return GetConstantInt32(&constant_1_, 1); | 608 return GetConstantInt32(&constant_1_, 1); |
| 619 } | 609 } |
| 620 | 610 |
| 621 | 611 |
| 622 HConstant* HGraph::GetConstantMinus1() { | 612 HConstant* HGraph::GetConstantMinus1() { |
| 623 return GetConstantInt32(&constant_minus1_, -1); | 613 return GetConstantInt32(&constant_minus1_, -1); |
| 624 } | 614 } |
| 625 | 615 |
| 626 | 616 |
| 627 HConstant* HGraph::GetConstantTrue() { | 617 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \ |
| 628 return GetConstant(&constant_true_, isolate()->factory()->true_value()); | 618 HConstant* HGraph::GetConstant##Name() { \ |
| 619 if (!constant_##name##_.is_set()) { \ |
| 620 HConstant* constant = new(zone()) HConstant( \ |
| 621 isolate()->factory()->name##_value(), \ |
| 622 Representation::Tagged(), \ |
| 623 htype, \ |
| 624 false, \ |
| 625 boolean_value); \ |
| 626 constant->InsertAfter(GetConstantUndefined()); \ |
| 627 constant_##name##_.set(constant); \ |
| 628 } \ |
| 629 return constant_##name##_.get(); \ |
| 629 } | 630 } |
| 630 | 631 |
| 631 | 632 |
| 632 HConstant* HGraph::GetConstantFalse() { | 633 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) |
| 633 return GetConstant(&constant_false_, isolate()->factory()->false_value()); | 634 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) |
| 634 } | 635 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
| 635 | 636 |
| 636 | 637 #undef DEFINE_GET_CONSTANT |
| 637 HConstant* HGraph::GetConstantHole() { | |
| 638 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); | |
| 639 } | |
| 640 | 638 |
| 641 | 639 |
| 642 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id) | 640 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id) |
| 643 : builder_(builder), | 641 : builder_(builder), |
| 644 finished_(false), | 642 finished_(false), |
| 645 id_(id) { | 643 id_(id) { |
| 646 HEnvironment* env = builder->environment(); | 644 HEnvironment* env = builder->environment(); |
| 647 failure_block_ = builder->CreateBasicBlock(env->Copy()); | 645 failure_block_ = builder->CreateBasicBlock(env->Copy()); |
| 648 merge_block_ = builder->CreateBasicBlock(env->Copy()); | 646 merge_block_ = builder->CreateBasicBlock(env->Copy()); |
| 649 } | 647 } |
| (...skipping 3054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3704 // We expect the graph to be in edge-split form: there is no edge that | 3702 // We expect the graph to be in edge-split form: there is no edge that |
| 3705 // connects a branch node to a join node. We conservatively ensure that | 3703 // connects a branch node to a join node. We conservatively ensure that |
| 3706 // property by always adding an empty block on the outgoing edges of this | 3704 // property by always adding an empty block on the outgoing edges of this |
| 3707 // branch. | 3705 // branch. |
| 3708 HOptimizedGraphBuilder* builder = owner(); | 3706 HOptimizedGraphBuilder* builder = owner(); |
| 3709 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { | 3707 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) { |
| 3710 builder->Bailout("arguments object value in a test context"); | 3708 builder->Bailout("arguments object value in a test context"); |
| 3711 } | 3709 } |
| 3712 if (value->IsConstant()) { | 3710 if (value->IsConstant()) { |
| 3713 HConstant* constant_value = HConstant::cast(value); | 3711 HConstant* constant_value = HConstant::cast(value); |
| 3714 if (constant_value->ToBoolean()) { | 3712 if (constant_value->BooleanValue()) { |
| 3715 builder->current_block()->Goto(if_true(), builder->function_state()); | 3713 builder->current_block()->Goto(if_true(), builder->function_state()); |
| 3716 } else { | 3714 } else { |
| 3717 builder->current_block()->Goto(if_false(), builder->function_state()); | 3715 builder->current_block()->Goto(if_false(), builder->function_state()); |
| 3718 } | 3716 } |
| 3719 builder->set_current_block(NULL); | 3717 builder->set_current_block(NULL); |
| 3720 return; | 3718 return; |
| 3721 } | 3719 } |
| 3722 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 3720 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
| 3723 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 3721 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
| 3724 TypeFeedbackId test_id = condition()->test_id(); | 3722 TypeFeedbackId test_id = condition()->test_id(); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3871 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | 3869 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
| 3872 type_info->set_inlined_type_change_checksum(composite_checksum); | 3870 type_info->set_inlined_type_change_checksum(composite_checksum); |
| 3873 | 3871 |
| 3874 return true; | 3872 return true; |
| 3875 } | 3873 } |
| 3876 | 3874 |
| 3877 | 3875 |
| 3878 void HGraph::GlobalValueNumbering() { | 3876 void HGraph::GlobalValueNumbering() { |
| 3879 // Perform common subexpression elimination and loop-invariant code motion. | 3877 // Perform common subexpression elimination and loop-invariant code motion. |
| 3880 if (FLAG_use_gvn) { | 3878 if (FLAG_use_gvn) { |
| 3879 // We use objects' raw addresses for identification, so they must not move. |
| 3880 Heap::RelocationLock relocation_lock(isolate()->heap()); |
| 3881 HPhase phase("H_Global value numbering", this); | 3881 HPhase phase("H_Global value numbering", this); |
| 3882 HGlobalValueNumberer gvn(this, info()); | 3882 HGlobalValueNumberer gvn(this, info()); |
| 3883 bool removed_side_effects = gvn.Analyze(); | 3883 bool removed_side_effects = gvn.Analyze(); |
| 3884 // Trigger a second analysis pass to further eliminate duplicate values that | 3884 // Trigger a second analysis pass to further eliminate duplicate values that |
| 3885 // could only be discovered by removing side-effect-generating instructions | 3885 // could only be discovered by removing side-effect-generating instructions |
| 3886 // during the first pass. | 3886 // during the first pass. |
| 3887 if (FLAG_smi_only_arrays && removed_side_effects) { | 3887 if (FLAG_smi_only_arrays && removed_side_effects) { |
| 3888 removed_side_effects = gvn.Analyze(); | 3888 removed_side_effects = gvn.Analyze(); |
| 3889 ASSERT(!removed_side_effects); | 3889 ASSERT(!removed_side_effects); |
| 3890 } | 3890 } |
| (...skipping 5343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9234 Visit(expr->right()); | 9234 Visit(expr->right()); |
| 9235 } | 9235 } |
| 9236 | 9236 |
| 9237 } else if (ast_context()->IsValue()) { | 9237 } else if (ast_context()->IsValue()) { |
| 9238 CHECK_ALIVE(VisitForValue(expr->left())); | 9238 CHECK_ALIVE(VisitForValue(expr->left())); |
| 9239 ASSERT(current_block() != NULL); | 9239 ASSERT(current_block() != NULL); |
| 9240 HValue* left_value = Top(); | 9240 HValue* left_value = Top(); |
| 9241 | 9241 |
| 9242 if (left_value->IsConstant()) { | 9242 if (left_value->IsConstant()) { |
| 9243 HConstant* left_constant = HConstant::cast(left_value); | 9243 HConstant* left_constant = HConstant::cast(left_value); |
| 9244 if ((is_logical_and && left_constant->ToBoolean()) || | 9244 if ((is_logical_and && left_constant->BooleanValue()) || |
| 9245 (!is_logical_and && !left_constant->ToBoolean())) { | 9245 (!is_logical_and && !left_constant->BooleanValue())) { |
| 9246 Drop(1); // left_value. | 9246 Drop(1); // left_value. |
| 9247 CHECK_BAILOUT(VisitForValue(expr->right())); | 9247 CHECK_BAILOUT(VisitForValue(expr->right())); |
| 9248 } | 9248 } |
| 9249 return ast_context()->ReturnValue(Pop()); | 9249 return ast_context()->ReturnValue(Pop()); |
| 9250 } | 9250 } |
| 9251 | 9251 |
| 9252 // We need an extra block to maintain edge-split form. | 9252 // We need an extra block to maintain edge-split form. |
| 9253 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | 9253 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| 9254 HBasicBlock* eval_right = graph()->CreateBasicBlock(); | 9254 HBasicBlock* eval_right = graph()->CreateBasicBlock(); |
| 9255 TypeFeedbackId test_id = expr->left()->test_id(); | 9255 TypeFeedbackId test_id = expr->left()->test_id(); |
| (...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10571 } else { | 10571 } else { |
| 10572 CodeStub::Major major_key = info->code_stub()->MajorKey(); | 10572 CodeStub::Major major_key = info->code_stub()->MajorKey(); |
| 10573 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); | 10573 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); |
| 10574 PrintStringProperty("method", "stub"); | 10574 PrintStringProperty("method", "stub"); |
| 10575 } | 10575 } |
| 10576 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); | 10576 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); |
| 10577 } | 10577 } |
| 10578 | 10578 |
| 10579 | 10579 |
| 10580 void HTracer::TraceLithium(const char* name, LChunk* chunk) { | 10580 void HTracer::TraceLithium(const char* name, LChunk* chunk) { |
| 10581 AllowHandleDereference allow_handle_deref(chunk->isolate()); | 10581 ASSERT(!FLAG_parallel_recompilation); |
| 10582 HandleDereferenceGuard allow_handle_deref(chunk->isolate(), |
| 10583 HandleDereferenceGuard::ALLOW); |
| 10582 Trace(name, chunk->graph(), chunk); | 10584 Trace(name, chunk->graph(), chunk); |
| 10583 } | 10585 } |
| 10584 | 10586 |
| 10585 | 10587 |
| 10586 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { | 10588 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { |
| 10587 AllowHandleDereference allow_handle_deref(graph->isolate()); | 10589 ASSERT(!FLAG_parallel_recompilation); |
| 10590 HandleDereferenceGuard allow_handle_deref(graph->isolate(), |
| 10591 HandleDereferenceGuard::ALLOW); |
| 10588 Trace(name, graph, NULL); | 10592 Trace(name, graph, NULL); |
| 10589 } | 10593 } |
| 10590 | 10594 |
| 10591 | 10595 |
| 10592 void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { | 10596 void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { |
| 10593 Tag tag(this, "cfg"); | 10597 Tag tag(this, "cfg"); |
| 10594 PrintStringProperty("name", name); | 10598 PrintStringProperty("name", name); |
| 10595 const ZoneList<HBasicBlock*>* blocks = graph->blocks(); | 10599 const ZoneList<HBasicBlock*>* blocks = graph->blocks(); |
| 10596 for (int i = 0; i < blocks->length(); i++) { | 10600 for (int i = 0; i < blocks->length(); i++) { |
| 10597 HBasicBlock* current = blocks->at(i); | 10601 HBasicBlock* current = blocks->at(i); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10928 } | 10932 } |
| 10929 } | 10933 } |
| 10930 | 10934 |
| 10931 #ifdef DEBUG | 10935 #ifdef DEBUG |
| 10932 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10936 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 10933 if (allocator_ != NULL) allocator_->Verify(); | 10937 if (allocator_ != NULL) allocator_->Verify(); |
| 10934 #endif | 10938 #endif |
| 10935 } | 10939 } |
| 10936 | 10940 |
| 10937 } } // namespace v8::internal | 10941 } } // namespace v8::internal |
| OLD | NEW |