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 |