Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: src/hydrogen.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-environment-liveness.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 void HGraphBuilder::IfBuilder::Then() { 798 void HGraphBuilder::IfBuilder::Then() {
799 ASSERT(!captured_); 799 ASSERT(!captured_);
800 ASSERT(!finished_); 800 ASSERT(!finished_);
801 did_then_ = true; 801 did_then_ = true;
802 if (needs_compare_) { 802 if (needs_compare_) {
803 // Handle if's without any expressions, they jump directly to the "else" 803 // Handle if's without any expressions, they jump directly to the "else"
804 // branch. However, we must pretend that the "then" branch is reachable, 804 // branch. However, we must pretend that the "then" branch is reachable,
805 // so that the graph builder visits it and sees any live range extending 805 // so that the graph builder visits it and sees any live range extending
806 // constructs within it. 806 // constructs within it.
807 HConstant* constant_false = builder_->graph()->GetConstantFalse(); 807 HConstant* constant_false = builder_->graph()->GetConstantFalse();
808 ToBooleanStub::Types boolean_type = ToBooleanStub::no_types(); 808 ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
809 boolean_type.Add(ToBooleanStub::BOOLEAN); 809 boolean_type.Add(ToBooleanStub::BOOLEAN);
810 HBranch* branch = 810 HBranch* branch =
811 new(zone()) HBranch(constant_false, first_true_block_, 811 new(zone()) HBranch(constant_false, first_true_block_,
812 first_false_block_, boolean_type); 812 first_false_block_, boolean_type);
813 builder_->current_block()->Finish(branch); 813 builder_->current_block()->Finish(branch);
814 } 814 }
815 builder_->set_current_block(first_true_block_); 815 builder_->set_current_block(first_true_block_);
816 } 816 }
817 817
818 818
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 builder_->set_current_block(exit_block_); 958 builder_->set_current_block(exit_block_);
959 // Pop the phi from the expression stack 959 // Pop the phi from the expression stack
960 builder_->environment()->Pop(); 960 builder_->environment()->Pop();
961 finished_ = true; 961 finished_ = true;
962 } 962 }
963 963
964 964
965 HGraph* HGraphBuilder::CreateGraph() { 965 HGraph* HGraphBuilder::CreateGraph() {
966 graph_ = new(zone()) HGraph(info_); 966 graph_ = new(zone()) HGraph(info_);
967 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 967 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
968 HPhase phase("H_Block building", isolate(), zone()); 968 CompilationPhase phase("H_Block building", info_);
969 set_current_block(graph()->entry_block()); 969 set_current_block(graph()->entry_block());
970 if (!BuildGraph()) return NULL; 970 if (!BuildGraph()) return NULL;
971 graph()->FinalizeUniqueValueIds(); 971 graph()->FinalizeUniqueValueIds();
972 return graph_; 972 return graph_;
973 } 973 }
974 974
975 975
976 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 976 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
977 ASSERT(current_block() != NULL); 977 ASSERT(current_block() != NULL);
978 current_block()->AddInstruction(instr); 978 current_block()->AddInstruction(instr);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 1019
1020 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 1020 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
1021 HBasicBlock* header = graph()->CreateBasicBlock(); 1021 HBasicBlock* header = graph()->CreateBasicBlock();
1022 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1022 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
1023 header->SetInitialEnvironment(entry_env); 1023 header->SetInitialEnvironment(entry_env);
1024 header->AttachLoopInformation(); 1024 header->AttachLoopInformation();
1025 return header; 1025 return header;
1026 } 1026 }
1027 1027
1028 1028
1029 HValue* HGraphBuilder::BuildCheckNonSmi(HValue* obj) { 1029 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1030 if (obj->type().IsHeapObject()) return obj; 1030 if (obj->type().IsHeapObject()) return obj;
1031 HCheckNonSmi* check = new(zone()) HCheckNonSmi(obj); 1031 HCheckHeapObject* check = new(zone()) HCheckHeapObject(obj);
1032 AddInstruction(check); 1032 AddInstruction(check);
1033 return check; 1033 return check;
1034 } 1034 }
1035 1035
1036 1036
1037 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, 1037 HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
1038 Handle<Map> map) { 1038 Handle<Map> map) {
1039 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); 1039 HCheckMaps* check = HCheckMaps::New(obj, map, zone());
1040 AddInstruction(check); 1040 AddInstruction(check);
1041 return check; 1041 return check;
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 graph()->GetConstantUndefined()); 1698 graph()->GetConstantUndefined());
1699 needs_or = true; 1699 needs_or = true;
1700 } 1700 }
1701 if (type->Maybe(Type::Undetectable())) { 1701 if (type->Maybe(Type::Undetectable())) {
1702 if (needs_or) if_nil.Or(); 1702 if (needs_or) if_nil.Or();
1703 if_nil.If<HIsUndetectableAndBranch>(value); 1703 if_nil.If<HIsUndetectableAndBranch>(value);
1704 } else { 1704 } else {
1705 if_nil.Then(); 1705 if_nil.Then();
1706 if_nil.Else(); 1706 if_nil.Else();
1707 if (type->NumClasses() == 1) { 1707 if (type->NumClasses() == 1) {
1708 BuildCheckNonSmi(value); 1708 BuildCheckHeapObject(value);
1709 // For ICs, the map checked below is a sentinel map that gets replaced by 1709 // For ICs, the map checked below is a sentinel map that gets replaced by
1710 // the monomorphic map when the code is used as a template to generate a 1710 // the monomorphic map when the code is used as a template to generate a
1711 // new IC. For optimized functions, there is no sentinel map, the map 1711 // new IC. For optimized functions, there is no sentinel map, the map
1712 // emitted below is the actual monomorphic map. 1712 // emitted below is the actual monomorphic map.
1713 BuildCheckMap(value, type->Classes().Current()); 1713 BuildCheckMap(value, type->Classes().Current());
1714 } else { 1714 } else {
1715 if_nil.Deopt(); 1715 if_nil.Deopt();
1716 } 1716 }
1717 } 1717 }
1718 1718
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 HLoopInformation* loop_; 2379 HLoopInformation* loop_;
2380 HBasicBlock* block_; 2380 HBasicBlock* block_;
2381 HBasicBlock* loop_header_; 2381 HBasicBlock* loop_header_;
2382 int loop_index; 2382 int loop_index;
2383 int loop_length; 2383 int loop_length;
2384 HSuccessorIterator successor_iterator; 2384 HSuccessorIterator successor_iterator;
2385 }; 2385 };
2386 2386
2387 2387
2388 void HGraph::OrderBlocks() { 2388 void HGraph::OrderBlocks() {
2389 HPhase phase("H_Block ordering", isolate(), zone()); 2389 CompilationPhase phase("H_Block ordering", info());
2390 BitVector visited(blocks_.length(), zone()); 2390 BitVector visited(blocks_.length(), zone());
2391 2391
2392 ZoneList<HBasicBlock*> reverse_result(8, zone()); 2392 ZoneList<HBasicBlock*> reverse_result(8, zone());
2393 HBasicBlock* start = blocks_[0]; 2393 HBasicBlock* start = blocks_[0];
2394 PostorderProcessor* postorder = 2394 PostorderProcessor* postorder =
2395 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited); 2395 PostorderProcessor::CreateEntryProcessor(zone(), start, &visited);
2396 while (postorder != NULL) { 2396 while (postorder != NULL) {
2397 postorder = postorder->PerformStep(zone(), &visited, &reverse_result); 2397 postorder = postorder->PerformStep(zone(), &visited, &reverse_result);
2398 } 2398 }
2399 blocks_.Rewind(0); 2399 blocks_.Rewind(0);
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
2684 Analyze(block->dominated_blocks()->at(i)); 2684 Analyze(block->dominated_blocks()->at(i));
2685 } 2685 }
2686 2686
2687 RollBackTo(last_changed_range); 2687 RollBackTo(last_changed_range);
2688 } 2688 }
2689 2689
2690 2690
2691 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test, 2691 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test,
2692 HBasicBlock* dest) { 2692 HBasicBlock* dest) {
2693 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 2693 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
2694 if (test->representation().IsInteger32()) { 2694 if (test->representation().IsSmiOrInteger32()) {
2695 Token::Value op = test->token(); 2695 Token::Value op = test->token();
2696 if (test->SecondSuccessor() == dest) { 2696 if (test->SecondSuccessor() == dest) {
2697 op = Token::NegateCompareOp(op); 2697 op = Token::NegateCompareOp(op);
2698 } 2698 }
2699 Token::Value inverted_op = Token::ReverseCompareOp(op); 2699 Token::Value inverted_op = Token::ReverseCompareOp(op);
2700 UpdateControlFlowRange(op, test->left(), test->right()); 2700 UpdateControlFlowRange(op, test->left(), test->right());
2701 UpdateControlFlowRange(inverted_op, test->right(), test->left()); 2701 UpdateControlFlowRange(inverted_op, test->right(), test->left());
2702 } 2702 }
2703 } 2703 }
2704 2704
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 for (int j = 0; j < phis->length(); ++j) { 2948 for (int j = 0; j < phis->length(); ++j) {
2949 HPhi* phi = phis->at(j); 2949 HPhi* phi = phis->at(j);
2950 if (phi->representation().IsNone()) { 2950 if (phi->representation().IsNone()) {
2951 phi->ChangeRepresentation(Representation::Tagged()); 2951 phi->ChangeRepresentation(Representation::Tagged());
2952 } 2952 }
2953 } 2953 }
2954 for (HInstruction* current = block->first(); 2954 for (HInstruction* current = block->first();
2955 current != NULL; current = current->next()) { 2955 current != NULL; current = current->next()) {
2956 if (current->representation().IsNone() && 2956 if (current->representation().IsNone() &&
2957 current->CheckFlag(HInstruction::kFlexibleRepresentation)) { 2957 current->CheckFlag(HInstruction::kFlexibleRepresentation)) {
2958 current->ChangeRepresentation(Representation::Tagged()); 2958 if (current->CheckFlag(HInstruction::kCannotBeTagged)) {
2959 current->ChangeRepresentation(Representation::Double());
2960 } else {
2961 current->ChangeRepresentation(Representation::Tagged());
2962 }
2959 } 2963 }
2960 } 2964 }
2961 } 2965 }
2962 } 2966 }
2963 2967
2964 2968
2965 void HGraph::MergeRemovableSimulates() { 2969 void HGraph::MergeRemovableSimulates() {
2966 HPhase phase("H_Merge removable simulates", this); 2970 HPhase phase("H_Merge removable simulates", this);
2967 ZoneList<HSimulate*> mergelist(2, zone()); 2971 ZoneList<HSimulate*> mergelist(2, zone());
2968 for (int i = 0; i < blocks()->length(); ++i) { 2972 for (int i = 0; i < blocks()->length(); ++i) {
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
3937 int checksum = type_info->own_type_change_checksum(); 3941 int checksum = type_info->own_type_change_checksum();
3938 int composite_checksum = graph()->update_type_change_checksum(checksum); 3942 int composite_checksum = graph()->update_type_change_checksum(checksum);
3939 graph()->set_use_optimistic_licm( 3943 graph()->set_use_optimistic_licm(
3940 !type_info->matches_inlined_type_change_checksum(composite_checksum)); 3944 !type_info->matches_inlined_type_change_checksum(composite_checksum));
3941 type_info->set_inlined_type_change_checksum(composite_checksum); 3945 type_info->set_inlined_type_change_checksum(composite_checksum);
3942 3946
3943 return true; 3947 return true;
3944 } 3948 }
3945 3949
3946 3950
3947 // Perform common subexpression elimination and loop-invariant code motion.
3948 void HGraph::GlobalValueNumbering() {
3949 HPhase phase("H_Global value numbering", this);
3950 HGlobalValueNumberer gvn(this, info());
3951 bool removed_side_effects = gvn.Analyze();
3952 // Trigger a second analysis pass to further eliminate duplicate values that
3953 // could only be discovered by removing side-effect-generating instructions
3954 // during the first pass.
3955 if (FLAG_smi_only_arrays && removed_side_effects) {
3956 removed_side_effects = gvn.Analyze();
3957 ASSERT(!removed_side_effects);
3958 }
3959 }
3960
3961
3962 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { 3951 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
3963 *bailout_reason = SmartArrayPointer<char>(); 3952 *bailout_reason = SmartArrayPointer<char>();
3964 OrderBlocks(); 3953 OrderBlocks();
3965 AssignDominators(); 3954 AssignDominators();
3966 3955
3967 // We need to create a HConstant "zero" now so that GVN will fold every 3956 // We need to create a HConstant "zero" now so that GVN will fold every
3968 // zero-valued constant in the graph together. 3957 // zero-valued constant in the graph together.
3969 // The constant is needed to make idef-based bounds check work: the pass 3958 // The constant is needed to make idef-based bounds check work: the pass
3970 // evaluates relations with "zero" and that zero cannot be created after GVN. 3959 // evaluates relations with "zero" and that zero cannot be created after GVN.
3971 GetConstant0(); 3960 GetConstant0();
3972 3961
3973 #ifdef DEBUG 3962 #ifdef DEBUG
3974 // Do a full verify after building the graph and computing dominators. 3963 // Do a full verify after building the graph and computing dominators.
3975 Verify(true); 3964 Verify(true);
3976 #endif 3965 #endif
3977 3966
3978 if (FLAG_analyze_environment_liveness) { 3967 if (FLAG_analyze_environment_liveness && maximum_environment_size() != 0) {
3979 EnvironmentSlotLivenessAnalyzer esla(this); 3968 Run<HEnvironmentLivenessAnalysisPhase>();
3980 esla.AnalyzeAndTrim();
3981 } 3969 }
3982 3970
3983 PropagateDeoptimizingMark(); 3971 PropagateDeoptimizingMark();
3984 if (!CheckConstPhiUses()) { 3972 if (!CheckConstPhiUses()) {
3985 *bailout_reason = SmartArrayPointer<char>(StrDup( 3973 *bailout_reason = SmartArrayPointer<char>(StrDup(
3986 "Unsupported phi use of const variable")); 3974 "Unsupported phi use of const variable"));
3987 return false; 3975 return false;
3988 } 3976 }
3989 EliminateRedundantPhis(); 3977 EliminateRedundantPhis();
3990 if (!CheckArgumentsPhiUses()) { 3978 if (!CheckArgumentsPhiUses()) {
(...skipping 29 matching lines...) Expand all
4020 4008
4021 InitializeInferredTypes(); 4009 InitializeInferredTypes();
4022 4010
4023 // Must be performed before canonicalization to ensure that Canonicalize 4011 // Must be performed before canonicalization to ensure that Canonicalize
4024 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with 4012 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
4025 // zero. 4013 // zero.
4026 if (FLAG_opt_safe_uint32_operations) ComputeSafeUint32Operations(); 4014 if (FLAG_opt_safe_uint32_operations) ComputeSafeUint32Operations();
4027 4015
4028 if (FLAG_use_canonicalizing) Canonicalize(); 4016 if (FLAG_use_canonicalizing) Canonicalize();
4029 4017
4030 if (FLAG_use_gvn) GlobalValueNumbering(); 4018 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>();
4031 4019
4032 if (FLAG_use_range) { 4020 if (FLAG_use_range) {
4033 HRangeAnalysis rangeAnalysis(this); 4021 HRangeAnalysis rangeAnalysis(this);
4034 rangeAnalysis.Analyze(); 4022 rangeAnalysis.Analyze();
4035 } 4023 }
4036 ComputeMinusZeroChecks(); 4024 ComputeMinusZeroChecks();
4037 4025
4038 // Eliminate redundant stack checks on backwards branches. 4026 // Eliminate redundant stack checks on backwards branches.
4039 HStackCheckEliminator sce(this); 4027 HStackCheckEliminator sce(this);
4040 sce.Process(); 4028 sce.Process();
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
4642 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 4630 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand());
4643 } else { 4631 } else {
4644 instruction->ReplaceAllUsesWith(instruction->ActualValue()); 4632 instruction->ReplaceAllUsesWith(instruction->ActualValue());
4645 } 4633 }
4646 } 4634 }
4647 } 4635 }
4648 } 4636 }
4649 } 4637 }
4650 4638
4651 4639
4652 void HOptimizedGraphBuilder::AddPhi(HPhi* instr) {
4653 ASSERT(current_block() != NULL);
4654 current_block()->AddPhi(instr);
4655 }
4656
4657
4658 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { 4640 void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) {
4659 Push(instr); 4641 Push(instr);
4660 AddInstruction(instr); 4642 AddInstruction(instr);
4661 } 4643 }
4662 4644
4663 4645
4664 void HOptimizedGraphBuilder::AddSoftDeoptimize() { 4646 void HOptimizedGraphBuilder::AddSoftDeoptimize() {
4647 isolate()->counters()->soft_deopts_requested()->Increment();
4665 if (FLAG_always_opt) return; 4648 if (FLAG_always_opt) return;
4666 if (current_block()->IsDeoptimizing()) return; 4649 if (current_block()->IsDeoptimizing()) return;
4667 AddInstruction(new(zone()) HSoftDeoptimize()); 4650 AddInstruction(new(zone()) HSoftDeoptimize());
4651 isolate()->counters()->soft_deopts_inserted()->Increment();
4668 current_block()->MarkAsDeoptimizing(); 4652 current_block()->MarkAsDeoptimizing();
4669 graph()->set_has_soft_deoptimize(true); 4653 graph()->set_has_soft_deoptimize(true);
4670 } 4654 }
4671 4655
4672 4656
4673 template <class Instruction> 4657 template <class Instruction>
4674 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { 4658 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
4675 int count = call->argument_count(); 4659 int count = call->argument_count();
4676 ZoneList<HValue*> arguments(count, zone()); 4660 ZoneList<HValue*> arguments(count, zone());
4677 for (int i = 0; i < count; ++i) { 4661 for (int i = 0; i < count; ++i) {
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
5010 // Generate a compare and branch. 4994 // Generate a compare and branch.
5011 CHECK_ALIVE(VisitForValue(clause->label())); 4995 CHECK_ALIVE(VisitForValue(clause->label()));
5012 HValue* label_value = Pop(); 4996 HValue* label_value = Pop();
5013 4997
5014 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 4998 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
5015 HBasicBlock* body_block = graph()->CreateBasicBlock(); 4999 HBasicBlock* body_block = graph()->CreateBasicBlock();
5016 5000
5017 HControlInstruction* compare; 5001 HControlInstruction* compare;
5018 5002
5019 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { 5003 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
5020 if (!clause->compare_type()->Is(Type::Integer31())) { 5004 if (!clause->compare_type()->Is(Type::Smi())) {
5021 AddSoftDeoptimize(); 5005 AddSoftDeoptimize();
5022 } 5006 }
5023 5007
5024 HCompareIDAndBranch* compare_ = 5008 HCompareIDAndBranch* compare_ =
5025 new(zone()) HCompareIDAndBranch(tag_value, 5009 new(zone()) HCompareIDAndBranch(tag_value,
5026 label_value, 5010 label_value,
5027 Token::EQ_STRICT); 5011 Token::EQ_STRICT);
5028 compare_->set_observed_input_representation( 5012 compare_->set_observed_input_representation(
5029 Representation::Smi(), Representation::Smi()); 5013 Representation::Smi(), Representation::Smi());
5030 compare = compare_; 5014 compare = compare_;
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
5666 case Variable::LOOKUP: 5650 case Variable::LOOKUP:
5667 return Bailout("reference to a variable which requires dynamic lookup"); 5651 return Bailout("reference to a variable which requires dynamic lookup");
5668 } 5652 }
5669 } 5653 }
5670 5654
5671 5655
5672 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 5656 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
5673 ASSERT(!HasStackOverflow()); 5657 ASSERT(!HasStackOverflow());
5674 ASSERT(current_block() != NULL); 5658 ASSERT(current_block() != NULL);
5675 ASSERT(current_block()->HasPredecessor()); 5659 ASSERT(current_block()->HasPredecessor());
5676 HConstant* instr = new(zone()) HConstant(expr->handle()); 5660 HConstant* instr = new(zone()) HConstant(expr->value());
5677 return ast_context()->ReturnInstruction(instr, expr->id()); 5661 return ast_context()->ReturnInstruction(instr, expr->id());
5678 } 5662 }
5679 5663
5680 5664
5681 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5665 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
5682 ASSERT(!HasStackOverflow()); 5666 ASSERT(!HasStackOverflow());
5683 ASSERT(current_block() != NULL); 5667 ASSERT(current_block() != NULL);
5684 ASSERT(current_block()->HasPredecessor()); 5668 ASSERT(current_block()->HasPredecessor());
5685 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5669 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5686 Handle<FixedArray> literals(closure->literals()); 5670 Handle<FixedArray> literals(closure->literals());
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5927 if (property->IsCompileTimeValue()) continue; 5911 if (property->IsCompileTimeValue()) continue;
5928 5912
5929 Literal* key = property->key(); 5913 Literal* key = property->key();
5930 Expression* value = property->value(); 5914 Expression* value = property->value();
5931 5915
5932 switch (property->kind()) { 5916 switch (property->kind()) {
5933 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 5917 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
5934 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 5918 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
5935 // Fall through. 5919 // Fall through.
5936 case ObjectLiteral::Property::COMPUTED: 5920 case ObjectLiteral::Property::COMPUTED:
5937 if (key->handle()->IsInternalizedString()) { 5921 if (key->value()->IsInternalizedString()) {
5938 if (property->emit_store()) { 5922 if (property->emit_store()) {
5939 CHECK_ALIVE(VisitForValue(value)); 5923 CHECK_ALIVE(VisitForValue(value));
5940 HValue* value = Pop(); 5924 HValue* value = Pop();
5941 Handle<Map> map = property->GetReceiverType(); 5925 Handle<Map> map = property->GetReceiverType();
5942 Handle<String> name = property->key()->AsPropertyName(); 5926 Handle<String> name = property->key()->AsPropertyName();
5943 HInstruction* store; 5927 HInstruction* store;
5944 if (map.is_null()) { 5928 if (map.is_null()) {
5945 // If we don't know the monomorphic type, do a generic store. 5929 // If we don't know the monomorphic type, do a generic store.
5946 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); 5930 CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value));
5947 } else { 5931 } else {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
6059 AddInstruction(new(zone()) HPushArgument(AddInstruction( 6043 AddInstruction(new(zone()) HPushArgument(AddInstruction(
6060 new(zone()) HConstant(constants)))); 6044 new(zone()) HConstant(constants))));
6061 6045
6062 Runtime::FunctionId function_id = (expr->depth() > 1) 6046 Runtime::FunctionId function_id = (expr->depth() > 1)
6063 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; 6047 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
6064 literal = AddInstruction( 6048 literal = AddInstruction(
6065 new(zone()) HCallRuntime(context, 6049 new(zone()) HCallRuntime(context,
6066 isolate()->factory()->empty_string(), 6050 isolate()->factory()->empty_string(),
6067 Runtime::FunctionForId(function_id), 6051 Runtime::FunctionForId(function_id),
6068 3)); 6052 3));
6053
6054 // De-opt if elements kind changed from boilerplate_elements_kind.
6055 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
6056 isolate());
6057 AddInstruction(HCheckMaps::New(literal, map, zone()));
6069 } 6058 }
6070 6059
6071 // The array is expected in the bailout environment during computation 6060 // The array is expected in the bailout environment during computation
6072 // of the property values and is the value of the entire expression. 6061 // of the property values and is the value of the entire expression.
6073 Push(literal); 6062 Push(literal);
6074 // The literal index is on the stack, too. 6063 // The literal index is on the stack, too.
6075 Push(AddInstruction(new(zone()) HConstant(expr->literal_index()))); 6064 Push(AddInstruction(new(zone()) HConstant(expr->literal_index())));
6076 6065
6077 HInstruction* elements = NULL; 6066 HInstruction* elements = NULL;
6078 6067
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
6148 Map* transition = lookup->GetTransitionMapFromMap(*type); 6137 Map* transition = lookup->GetTransitionMapFromMap(*type);
6149 int descriptor = transition->LastAdded(); 6138 int descriptor = transition->LastAdded();
6150 PropertyDetails details = 6139 PropertyDetails details =
6151 transition->instance_descriptors()->GetDetails(descriptor); 6140 transition->instance_descriptors()->GetDetails(descriptor);
6152 return details.representation(); 6141 return details.representation();
6153 } 6142 }
6154 } 6143 }
6155 6144
6156 6145
6157 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 6146 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
6158 BuildCheckNonSmi(object); 6147 BuildCheckHeapObject(object);
6159 AddInstruction(HCheckMaps::New(object, map, zone())); 6148 AddInstruction(HCheckMaps::New(object, map, zone()));
6160 } 6149 }
6161 6150
6162 6151
6163 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 6152 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
6164 Handle<Map> map) { 6153 Handle<Map> map) {
6165 BuildCheckNonSmi(object); 6154 BuildCheckHeapObject(object);
6166 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 6155 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
6167 } 6156 }
6168 6157
6169 6158
6170 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 6159 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
6171 HValue* object, 6160 HValue* object,
6172 Handle<String> name, 6161 Handle<String> name,
6173 HValue* value, 6162 HValue* value,
6174 Handle<Map> map, 6163 Handle<Map> map,
6175 LookupResult* lookup) { 6164 LookupResult* lookup) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
6324 } else if (access.IsInobject() != new_access.IsInobject()) { 6313 } else if (access.IsInobject() != new_access.IsInobject()) {
6325 // In-objectness did not match. 6314 // In-objectness did not match.
6326 break; 6315 break;
6327 } 6316 }
6328 representation = representation.generalize(new_representation); 6317 representation = representation.generalize(new_representation);
6329 } 6318 }
6330 6319
6331 if (count != types->length()) return NULL; 6320 if (count != types->length()) return NULL;
6332 6321
6333 // Everything matched; can use monomorphic load. 6322 // Everything matched; can use monomorphic load.
6334 BuildCheckNonSmi(object); 6323 BuildCheckHeapObject(object);
6335 AddInstruction(HCheckMaps::New(object, types, zone())); 6324 AddInstruction(HCheckMaps::New(object, types, zone()));
6336 return BuildLoadNamedField(object, access, representation); 6325 return BuildLoadNamedField(object, access, representation);
6337 } 6326 }
6338 6327
6339 6328
6340 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 6329 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
6341 Property* expr, 6330 Property* expr,
6342 HValue* object, 6331 HValue* object,
6343 SmallMapList* types, 6332 SmallMapList* types,
6344 Handle<String> name) { 6333 Handle<String> name) {
6345 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 6334 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
6346 expr, object, types, name); 6335 expr, object, types, name);
6347 if (instr == NULL) { 6336 if (instr == NULL) {
6348 // Something did not match; must use a polymorphic load. 6337 // Something did not match; must use a polymorphic load.
6349 BuildCheckNonSmi(object); 6338 BuildCheckHeapObject(object);
6350 HValue* context = environment()->LookupContext(); 6339 HValue* context = environment()->LookupContext();
6351 instr = new(zone()) HLoadNamedFieldPolymorphic( 6340 instr = new(zone()) HLoadNamedFieldPolymorphic(
6352 context, object, types, name, zone()); 6341 context, object, types, name, zone());
6353 } 6342 }
6354 6343
6355 instr->set_position(expr->position()); 6344 instr->set_position(expr->position());
6356 return ast_context()->ReturnInstruction(instr, expr->id()); 6345 return ast_context()->ReturnInstruction(instr, expr->id());
6357 } 6346 }
6358 6347
6359 6348
6360 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 6349 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
6361 Assignment* expr, 6350 int position,
6351 BailoutId assignment_id,
6362 HValue* object, 6352 HValue* object,
6363 HValue* value, 6353 HValue* value,
6364 SmallMapList* types, 6354 SmallMapList* types,
6365 Handle<String> name) { 6355 Handle<String> name) {
6366 // Use monomorphic store if property lookup results in the same field index 6356 // Use monomorphic store if property lookup results in the same field index
6367 // for all maps. Requires special map check on the set of all handled maps. 6357 // for all maps. Requires special map check on the set of all handled maps.
6368 if (types->length() > kMaxStorePolymorphism) return false; 6358 if (types->length() > kMaxStorePolymorphism) return false;
6369 6359
6370 // TODO(verwaest): Merge the checking logic with the code in 6360 // TODO(verwaest): Merge the checking logic with the code in
6371 // TryLoadPolymorphicAsMonomorphic. 6361 // TryLoadPolymorphicAsMonomorphic.
(...skipping 22 matching lines...) Expand all
6394 break; 6384 break;
6395 } else if (access.IsInobject() != new_access.IsInobject()) { 6385 } else if (access.IsInobject() != new_access.IsInobject()) {
6396 // In-objectness did not match. 6386 // In-objectness did not match.
6397 break; 6387 break;
6398 } 6388 }
6399 } 6389 }
6400 6390
6401 if (count != types->length()) return false; 6391 if (count != types->length()) return false;
6402 6392
6403 // Everything matched; can use monomorphic store. 6393 // Everything matched; can use monomorphic store.
6404 BuildCheckNonSmi(object); 6394 BuildCheckHeapObject(object);
6405 AddInstruction(HCheckMaps::New(object, types, zone())); 6395 AddInstruction(HCheckMaps::New(object, types, zone()));
6406 HInstruction* store; 6396 HInstruction* store;
6407 CHECK_ALIVE_OR_RETURN( 6397 CHECK_ALIVE_OR_RETURN(
6408 store = BuildStoreNamedField(object, name, value, types->at(0), &lookup), 6398 store = BuildStoreNamedField(
6399 object, name, value, types->at(count - 1), &lookup),
6409 true); 6400 true);
6410 Push(value); 6401 Push(value);
6411 store->set_position(expr->position()); 6402 store->set_position(position);
6412 AddInstruction(store); 6403 AddInstruction(store);
6413 AddSimulate(expr->AssignmentId()); 6404 AddSimulate(assignment_id);
6414 ast_context()->ReturnValue(Pop()); 6405 ast_context()->ReturnValue(Pop());
6415 return true; 6406 return true;
6416 } 6407 }
6417 6408
6418 6409
6419 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 6410 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
6420 Assignment* expr, 6411 BailoutId id,
6412 int position,
6413 BailoutId assignment_id,
6421 HValue* object, 6414 HValue* object,
6422 HValue* value, 6415 HValue* value,
6423 SmallMapList* types, 6416 SmallMapList* types,
6424 Handle<String> name) { 6417 Handle<String> name) {
6425 if (TryStorePolymorphicAsMonomorphic(expr, object, value, types, name)) { 6418 if (TryStorePolymorphicAsMonomorphic(
6419 position, assignment_id, object, value, types, name)) {
6426 return; 6420 return;
6427 } 6421 }
6428 6422
6429 // TODO(ager): We should recognize when the prototype chains for different 6423 // TODO(ager): We should recognize when the prototype chains for different
6430 // maps are identical. In that case we can avoid repeatedly generating the 6424 // maps are identical. In that case we can avoid repeatedly generating the
6431 // same prototype map checks. 6425 // same prototype map checks.
6432 int count = 0; 6426 int count = 0;
6433 HBasicBlock* join = NULL; 6427 HBasicBlock* join = NULL;
6434 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 6428 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
6435 Handle<Map> map = types->at(i); 6429 Handle<Map> map = types->at(i);
6436 LookupResult lookup(isolate()); 6430 LookupResult lookup(isolate());
6437 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6431 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6438 if (count == 0) { 6432 if (count == 0) {
6439 BuildCheckNonSmi(object); 6433 BuildCheckHeapObject(object);
6440 join = graph()->CreateBasicBlock(); 6434 join = graph()->CreateBasicBlock();
6441 } 6435 }
6442 ++count; 6436 ++count;
6443 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6437 HBasicBlock* if_true = graph()->CreateBasicBlock();
6444 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6438 HBasicBlock* if_false = graph()->CreateBasicBlock();
6445 HCompareMap* compare = 6439 HCompareMap* compare =
6446 new(zone()) HCompareMap(object, map, if_true, if_false); 6440 new(zone()) HCompareMap(object, map, if_true, if_false);
6447 current_block()->Finish(compare); 6441 current_block()->Finish(compare);
6448 6442
6449 set_current_block(if_true); 6443 set_current_block(if_true);
6450 HInstruction* instr; 6444 HInstruction* instr;
6451 CHECK_ALIVE( 6445 CHECK_ALIVE(
6452 instr = BuildStoreNamedField(object, name, value, map, &lookup)); 6446 instr = BuildStoreNamedField(object, name, value, map, &lookup));
6453 instr->set_position(expr->position()); 6447 instr->set_position(position);
6454 // Goto will add the HSimulate for the store. 6448 // Goto will add the HSimulate for the store.
6455 AddInstruction(instr); 6449 AddInstruction(instr);
6456 if (!ast_context()->IsEffect()) Push(value); 6450 if (!ast_context()->IsEffect()) Push(value);
6457 current_block()->Goto(join); 6451 current_block()->Goto(join);
6458 6452
6459 set_current_block(if_false); 6453 set_current_block(if_false);
6460 } 6454 }
6461 } 6455 }
6462 6456
6463 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6457 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6464 // know about and do not want to handle ones we've never seen. Otherwise 6458 // know about and do not want to handle ones we've never seen. Otherwise
6465 // use a generic IC. 6459 // use a generic IC.
6466 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6460 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6467 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 6461 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
6468 } else { 6462 } else {
6469 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 6463 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
6470 instr->set_position(expr->position()); 6464 instr->set_position(position);
6471 AddInstruction(instr); 6465 AddInstruction(instr);
6472 6466
6473 if (join != NULL) { 6467 if (join != NULL) {
6474 if (!ast_context()->IsEffect()) Push(value); 6468 if (!ast_context()->IsEffect()) Push(value);
6475 current_block()->Goto(join); 6469 current_block()->Goto(join);
6476 } else { 6470 } else {
6477 // The HSimulate for the store should not see the stored value in 6471 // The HSimulate for the store should not see the stored value in
6478 // effect contexts (it is not materialized at expr->id() in the 6472 // effect contexts (it is not materialized at expr->id() in the
6479 // unoptimized code). 6473 // unoptimized code).
6480 if (instr->HasObservableSideEffects()) { 6474 if (instr->HasObservableSideEffects()) {
6481 if (ast_context()->IsEffect()) { 6475 if (ast_context()->IsEffect()) {
6482 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6476 AddSimulate(id, REMOVABLE_SIMULATE);
6483 } else { 6477 } else {
6484 Push(value); 6478 Push(value);
6485 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6479 AddSimulate(id, REMOVABLE_SIMULATE);
6486 Drop(1); 6480 Drop(1);
6487 } 6481 }
6488 } 6482 }
6489 return ast_context()->ReturnValue(value); 6483 return ast_context()->ReturnValue(value);
6490 } 6484 }
6491 } 6485 }
6492 6486
6493 ASSERT(join != NULL); 6487 ASSERT(join != NULL);
6494 join->SetJoinId(expr->id()); 6488 join->SetJoinId(id);
6495 set_current_block(join); 6489 set_current_block(join);
6496 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6490 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6497 } 6491 }
6498 6492
6499 6493
6500 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6494 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6501 Property* prop = expr->target()->AsProperty(); 6495 Property* prop = expr->target()->AsProperty();
6502 ASSERT(prop != NULL); 6496 ASSERT(prop != NULL);
6503 CHECK_ALIVE(VisitForValue(prop->obj())); 6497 CHECK_ALIVE(VisitForValue(prop->obj()));
6504 6498
6505 if (prop->key()->IsPropertyName()) { 6499 if (prop->key()->IsPropertyName()) {
6506 // Named store. 6500 // Named store.
6507 CHECK_ALIVE(VisitForValue(expr->value())); 6501 CHECK_ALIVE(VisitForValue(expr->value()));
6508 HValue* value = environment()->ExpressionStackAt(0); 6502 HValue* value = environment()->ExpressionStackAt(0);
6509 HValue* object = environment()->ExpressionStackAt(1); 6503 HValue* object = environment()->ExpressionStackAt(1);
6510 6504
6511 Literal* key = prop->key()->AsLiteral(); 6505 if (expr->IsUninitialized()) AddSoftDeoptimize();
6512 Handle<String> name = Handle<String>::cast(key->handle()); 6506 return BuildStoreNamed(expr, expr->id(), expr->position(),
6513 ASSERT(!name.is_null()); 6507 expr->AssignmentId(), prop, object, value);
6514
6515 HInstruction* instr = NULL;
6516 SmallMapList* types = expr->GetReceiverTypes();
6517 bool monomorphic = expr->IsMonomorphic();
6518 Handle<Map> map;
6519 if (monomorphic) {
6520 map = types->first();
6521 if (map->is_dictionary_map()) monomorphic = false;
6522 }
6523 if (monomorphic) {
6524 Handle<JSFunction> setter;
6525 Handle<JSObject> holder;
6526 if (LookupSetter(map, name, &setter, &holder)) {
6527 AddCheckConstantFunction(holder, object, map);
6528 if (FLAG_inline_accessors && TryInlineSetter(setter, expr, value)) {
6529 return;
6530 }
6531 Drop(2);
6532 AddInstruction(new(zone()) HPushArgument(object));
6533 AddInstruction(new(zone()) HPushArgument(value));
6534 instr = new(zone()) HCallConstantFunction(setter, 2);
6535 } else {
6536 Drop(2);
6537 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
6538 name,
6539 value,
6540 map));
6541 }
6542
6543 } else if (types != NULL && types->length() > 1) {
6544 Drop(2);
6545 return HandlePolymorphicStoreNamedField(expr, object, value, types, name);
6546 } else {
6547 Drop(2);
6548 instr = BuildStoreNamedGeneric(object, name, value);
6549 }
6550
6551 Push(value);
6552 instr->set_position(expr->position());
6553 AddInstruction(instr);
6554 if (instr->HasObservableSideEffects()) {
6555 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
6556 }
6557 return ast_context()->ReturnValue(Pop());
6558
6559 } else { 6508 } else {
6560 // Keyed store. 6509 // Keyed store.
6561 CHECK_ALIVE(VisitForValue(prop->key())); 6510 CHECK_ALIVE(VisitForValue(prop->key()));
6562 CHECK_ALIVE(VisitForValue(expr->value())); 6511 CHECK_ALIVE(VisitForValue(expr->value()));
6563 HValue* value = environment()->ExpressionStackAt(0); 6512 HValue* value = environment()->ExpressionStackAt(0);
6564 HValue* key = environment()->ExpressionStackAt(1); 6513 HValue* key = environment()->ExpressionStackAt(1);
6565 HValue* object = environment()->ExpressionStackAt(2); 6514 HValue* object = environment()->ExpressionStackAt(2);
6566 bool has_side_effects = false; 6515 bool has_side_effects = false;
6567 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 6516 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
6568 expr->position(), 6517 expr->position(),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6607 value, 6556 value,
6608 function_strict_mode_flag()); 6557 function_strict_mode_flag());
6609 instr->set_position(position); 6558 instr->set_position(position);
6610 AddInstruction(instr); 6559 AddInstruction(instr);
6611 ASSERT(instr->HasObservableSideEffects()); 6560 ASSERT(instr->HasObservableSideEffects());
6612 AddSimulate(ast_id, REMOVABLE_SIMULATE); 6561 AddSimulate(ast_id, REMOVABLE_SIMULATE);
6613 } 6562 }
6614 } 6563 }
6615 6564
6616 6565
6566 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
6567 BailoutId id,
6568 int position,
6569 BailoutId assignment_id,
6570 Property* prop,
6571 HValue* object,
6572 HValue* value) {
6573 Literal* key = prop->key()->AsLiteral();
6574 Handle<String> name = Handle<String>::cast(key->value());
6575 ASSERT(!name.is_null());
6576
6577 HInstruction* instr = NULL;
6578 SmallMapList* types = expr->GetReceiverTypes();
6579 bool monomorphic = expr->IsMonomorphic();
6580 Handle<Map> map;
6581 if (monomorphic) {
6582 map = types->first();
6583 if (map->is_dictionary_map()) monomorphic = false;
6584 }
6585 if (monomorphic) {
6586 Handle<JSFunction> setter;
6587 Handle<JSObject> holder;
6588 if (LookupSetter(map, name, &setter, &holder)) {
6589 AddCheckConstantFunction(holder, object, map);
6590 if (FLAG_inline_accessors &&
6591 TryInlineSetter(setter, id, assignment_id, value)) {
6592 return;
6593 }
6594 Drop(2);
6595 AddInstruction(new(zone()) HPushArgument(object));
6596 AddInstruction(new(zone()) HPushArgument(value));
6597 instr = new(zone()) HCallConstantFunction(setter, 2);
6598 } else {
6599 Drop(2);
6600 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
6601 name,
6602 value,
6603 map));
6604 }
6605
6606 } else if (types != NULL && types->length() > 1) {
6607 Drop(2);
6608 return HandlePolymorphicStoreNamedField(
6609 id, position, assignment_id, object, value, types, name);
6610 } else {
6611 Drop(2);
6612 instr = BuildStoreNamedGeneric(object, name, value);
6613 }
6614
6615 Push(value);
6616 instr->set_position(position);
6617 AddInstruction(instr);
6618 if (instr->HasObservableSideEffects()) {
6619 AddSimulate(assignment_id, REMOVABLE_SIMULATE);
6620 }
6621 return ast_context()->ReturnValue(Pop());
6622 }
6623
6624
6617 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6625 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
6618 Expression* target = expr->target(); 6626 Expression* target = expr->target();
6619 VariableProxy* proxy = target->AsVariableProxy(); 6627 VariableProxy* proxy = target->AsVariableProxy();
6620 Property* prop = target->AsProperty(); 6628 Property* prop = target->AsProperty();
6621 ASSERT(proxy == NULL || prop == NULL); 6629 ASSERT(proxy == NULL || prop == NULL);
6622 6630
6623 // We have a second position recorded in the FullCodeGenerator to have 6631 // We have a second position recorded in the FullCodeGenerator to have
6624 // type feedback for the binary operation. 6632 // type feedback for the binary operation.
6625 BinaryOperation* operation = expr->binary_operation(); 6633 BinaryOperation* operation = expr->binary_operation();
6626 6634
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
6733 CHECK_ALIVE(VisitForValue(expr->value())); 6741 CHECK_ALIVE(VisitForValue(expr->value()));
6734 HValue* right = Pop(); 6742 HValue* right = Pop();
6735 HValue* left = Pop(); 6743 HValue* left = Pop();
6736 6744
6737 HInstruction* instr = BuildBinaryOperation(operation, left, right); 6745 HInstruction* instr = BuildBinaryOperation(operation, left, right);
6738 PushAndAdd(instr); 6746 PushAndAdd(instr);
6739 if (instr->HasObservableSideEffects()) { 6747 if (instr->HasObservableSideEffects()) {
6740 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 6748 AddSimulate(operation->id(), REMOVABLE_SIMULATE);
6741 } 6749 }
6742 6750
6743 HInstruction* store; 6751 return BuildStoreNamed(prop, expr->id(), expr->position(),
6744 if (!monomorphic || map->is_observed()) { 6752 expr->AssignmentId(), prop, object, instr);
6745 // If we don't know the monomorphic type, do a generic store.
6746 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
6747 } else {
6748 Handle<JSFunction> setter;
6749 Handle<JSObject> holder;
6750 if (LookupSetter(map, name, &setter, &holder)) {
6751 store = BuildCallSetter(object, instr, map, setter, holder);
6752 } else {
6753 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
6754 name,
6755 instr,
6756 map));
6757 }
6758 }
6759 AddInstruction(store);
6760 // Drop the simulated receiver and value. Return the value.
6761 Drop(2);
6762 Push(instr);
6763 if (store->HasObservableSideEffects()) {
6764 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
6765 }
6766 return ast_context()->ReturnValue(Pop());
6767
6768 } else { 6753 } else {
6769 // Keyed property. 6754 // Keyed property.
6770 CHECK_ALIVE(VisitForValue(prop->obj())); 6755 CHECK_ALIVE(VisitForValue(prop->obj()));
6771 CHECK_ALIVE(VisitForValue(prop->key())); 6756 CHECK_ALIVE(VisitForValue(prop->key()));
6772 HValue* obj = environment()->ExpressionStackAt(1); 6757 HValue* obj = environment()->ExpressionStackAt(1);
6773 HValue* key = environment()->ExpressionStackAt(0); 6758 HValue* key = environment()->ExpressionStackAt(0);
6774 6759
6775 bool has_side_effects = false; 6760 bool has_side_effects = false;
6776 HValue* load = HandleKeyedElementAccess( 6761 HValue* load = HandleKeyedElementAccess(
6777 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 6762 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
6983 return field; 6968 return field;
6984 } 6969 }
6985 6970
6986 6971
6987 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 6972 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
6988 HValue* object, 6973 HValue* object,
6989 Handle<String> name, 6974 Handle<String> name,
6990 Property* expr) { 6975 Property* expr) {
6991 if (expr->IsUninitialized()) { 6976 if (expr->IsUninitialized()) {
6992 AddSoftDeoptimize(); 6977 AddSoftDeoptimize();
6993 } else {
6994 // OS::DebugBreak();
6995 } 6978 }
6996 HValue* context = environment()->LookupContext(); 6979 HValue* context = environment()->LookupContext();
6997 return new(zone()) HLoadNamedGeneric(context, object, name); 6980 return new(zone()) HLoadNamedGeneric(context, object, name);
6998 } 6981 }
6999 6982
7000 6983
7001 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 6984 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
7002 HValue* object, 6985 HValue* object,
7003 Handle<Map> map, 6986 Handle<Map> map,
7004 Handle<JSFunction> getter, 6987 Handle<JSFunction> getter,
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
7174 HValue* object, 7157 HValue* object,
7175 HValue* key, 7158 HValue* key,
7176 HValue* val, 7159 HValue* val,
7177 Expression* prop, 7160 Expression* prop,
7178 BailoutId ast_id, 7161 BailoutId ast_id,
7179 int position, 7162 int position,
7180 bool is_store, 7163 bool is_store,
7181 KeyedAccessStoreMode store_mode, 7164 KeyedAccessStoreMode store_mode,
7182 bool* has_side_effects) { 7165 bool* has_side_effects) {
7183 *has_side_effects = false; 7166 *has_side_effects = false;
7184 BuildCheckNonSmi(object); 7167 BuildCheckHeapObject(object);
7185 SmallMapList* maps = prop->GetReceiverTypes(); 7168 SmallMapList* maps = prop->GetReceiverTypes();
7186 bool todo_external_array = false; 7169 bool todo_external_array = false;
7187 7170
7188 if (!is_store) { 7171 if (!is_store) {
7189 HInstruction* consolidated_load = 7172 HInstruction* consolidated_load =
7190 TryBuildConsolidatedElementLoad(object, key, val, maps); 7173 TryBuildConsolidatedElementLoad(object, key, val, maps);
7191 if (consolidated_load != NULL) { 7174 if (consolidated_load != NULL) {
7192 *has_side_effects |= consolidated_load->HasObservableSideEffects(); 7175 *has_side_effects |= consolidated_load->HasObservableSideEffects();
7193 if (position != RelocInfo::kNoPosition) { 7176 if (position != RelocInfo::kNoPosition) {
7194 consolidated_load->set_position(position); 7177 consolidated_load->set_position(position);
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
7399 bool* has_side_effects) { 7382 bool* has_side_effects) {
7400 ASSERT(!expr->IsPropertyName()); 7383 ASSERT(!expr->IsPropertyName());
7401 HInstruction* instr = NULL; 7384 HInstruction* instr = NULL;
7402 if (expr->IsMonomorphic()) { 7385 if (expr->IsMonomorphic()) {
7403 Handle<Map> map = expr->GetMonomorphicReceiverType(); 7386 Handle<Map> map = expr->GetMonomorphicReceiverType();
7404 if (map->has_slow_elements_kind()) { 7387 if (map->has_slow_elements_kind()) {
7405 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) 7388 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val)
7406 : BuildLoadKeyedGeneric(obj, key); 7389 : BuildLoadKeyedGeneric(obj, key);
7407 AddInstruction(instr); 7390 AddInstruction(instr);
7408 } else { 7391 } else {
7409 BuildCheckNonSmi(obj); 7392 BuildCheckHeapObject(obj);
7410 instr = BuildMonomorphicElementAccess( 7393 instr = BuildMonomorphicElementAccess(
7411 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); 7394 obj, key, val, NULL, map, is_store, expr->GetStoreMode());
7412 } 7395 }
7413 } else if (expr->GetReceiverTypes() != NULL && 7396 } else if (expr->GetReceiverTypes() != NULL &&
7414 !expr->GetReceiverTypes()->is_empty()) { 7397 !expr->GetReceiverTypes()->is_empty()) {
7415 return HandlePolymorphicElementAccess( 7398 return HandlePolymorphicElementAccess(
7416 obj, key, val, expr, ast_id, position, is_store, 7399 obj, key, val, expr, ast_id, position, is_store,
7417 expr->GetStoreMode(), has_side_effects); 7400 expr->GetStoreMode(), has_side_effects);
7418 } else { 7401 } else {
7419 if (is_store) { 7402 if (is_store) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7531 ASSERT(current_block() != NULL); 7514 ASSERT(current_block() != NULL);
7532 ASSERT(current_block()->HasPredecessor()); 7515 ASSERT(current_block()->HasPredecessor());
7533 7516
7534 if (TryArgumentsAccess(expr)) return; 7517 if (TryArgumentsAccess(expr)) return;
7535 7518
7536 CHECK_ALIVE(VisitForValue(expr->obj())); 7519 CHECK_ALIVE(VisitForValue(expr->obj()));
7537 7520
7538 HInstruction* instr = NULL; 7521 HInstruction* instr = NULL;
7539 if (expr->IsStringLength()) { 7522 if (expr->IsStringLength()) {
7540 HValue* string = Pop(); 7523 HValue* string = Pop();
7541 BuildCheckNonSmi(string); 7524 BuildCheckHeapObject(string);
7542 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 7525 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
7543 instr = HStringLength::New(zone(), string); 7526 instr = HStringLength::New(zone(), string);
7544 } else if (expr->IsStringAccess()) { 7527 } else if (expr->IsStringAccess()) {
7545 CHECK_ALIVE(VisitForValue(expr->key())); 7528 CHECK_ALIVE(VisitForValue(expr->key()));
7546 HValue* index = Pop(); 7529 HValue* index = Pop();
7547 HValue* string = Pop(); 7530 HValue* string = Pop();
7548 HValue* context = environment()->LookupContext(); 7531 HValue* context = environment()->LookupContext();
7549 HInstruction* char_code = 7532 HInstruction* char_code =
7550 BuildStringCharCodeAt(context, string, index); 7533 BuildStringCharCodeAt(context, string, index);
7551 AddInstruction(char_code); 7534 AddInstruction(char_code);
7552 instr = HStringCharFromCode::New(zone(), context, char_code); 7535 instr = HStringCharFromCode::New(zone(), context, char_code);
7553 7536
7554 } else if (expr->IsFunctionPrototype()) { 7537 } else if (expr->IsFunctionPrototype()) {
7555 HValue* function = Pop(); 7538 HValue* function = Pop();
7556 BuildCheckNonSmi(function); 7539 BuildCheckHeapObject(function);
7557 instr = new(zone()) HLoadFunctionPrototype(function); 7540 instr = new(zone()) HLoadFunctionPrototype(function);
7558 7541
7559 } else if (expr->key()->IsPropertyName()) { 7542 } else if (expr->key()->IsPropertyName()) {
7560 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 7543 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
7561 SmallMapList* types = expr->GetReceiverTypes(); 7544 SmallMapList* types = expr->GetReceiverTypes();
7562 HValue* object = Top(); 7545 HValue* object = Top();
7563 7546
7564 Handle<Map> map; 7547 Handle<Map> map;
7565 bool monomorphic = false; 7548 bool monomorphic = false;
7566 if (expr->IsMonomorphic()) { 7549 if (expr->IsMonomorphic()) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
7720 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 7703 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock();
7721 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 7704 HBasicBlock* not_smi_block = graph()->CreateBasicBlock();
7722 number_block = graph()->CreateBasicBlock(); 7705 number_block = graph()->CreateBasicBlock();
7723 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver); 7706 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(receiver);
7724 smicheck->SetSuccessorAt(0, empty_smi_block); 7707 smicheck->SetSuccessorAt(0, empty_smi_block);
7725 smicheck->SetSuccessorAt(1, not_smi_block); 7708 smicheck->SetSuccessorAt(1, not_smi_block);
7726 current_block()->Finish(smicheck); 7709 current_block()->Finish(smicheck);
7727 empty_smi_block->Goto(number_block); 7710 empty_smi_block->Goto(number_block);
7728 set_current_block(not_smi_block); 7711 set_current_block(not_smi_block);
7729 } else { 7712 } else {
7730 BuildCheckNonSmi(receiver); 7713 BuildCheckHeapObject(receiver);
7731 } 7714 }
7732 } 7715 }
7733 HBasicBlock* if_true = graph()->CreateBasicBlock(); 7716 HBasicBlock* if_true = graph()->CreateBasicBlock();
7734 HBasicBlock* if_false = graph()->CreateBasicBlock(); 7717 HBasicBlock* if_false = graph()->CreateBasicBlock();
7735 HUnaryControlInstruction* compare; 7718 HUnaryControlInstruction* compare;
7736 7719
7737 if (handle_smi && map.is_identical_to(number_marker_map)) { 7720 if (handle_smi && map.is_identical_to(number_marker_map)) {
7738 compare = new(zone()) HCompareMap( 7721 compare = new(zone()) HCompareMap(
7739 receiver, heap_number_map, if_true, if_false); 7722 receiver, heap_number_map, if_true, if_false);
7740 map = initial_number_map; 7723 map = initial_number_map;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
8220 getter, 8203 getter,
8221 0, 8204 0,
8222 NULL, 8205 NULL,
8223 prop->id(), 8206 prop->id(),
8224 prop->LoadId(), 8207 prop->LoadId(),
8225 GETTER_CALL_RETURN); 8208 GETTER_CALL_RETURN);
8226 } 8209 }
8227 8210
8228 8211
8229 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 8212 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
8230 Assignment* assignment, 8213 BailoutId id,
8214 BailoutId assignment_id,
8231 HValue* implicit_return_value) { 8215 HValue* implicit_return_value) {
8232 return TryInline(CALL_AS_METHOD, 8216 return TryInline(CALL_AS_METHOD,
8233 setter, 8217 setter,
8234 1, 8218 1,
8235 implicit_return_value, 8219 implicit_return_value,
8236 assignment->id(), 8220 id, assignment_id,
8237 assignment->AssignmentId(),
8238 SETTER_CALL_RETURN); 8221 SETTER_CALL_RETURN);
8239 } 8222 }
8240 8223
8241 8224
8242 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 8225 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function,
8243 Call* expr, 8226 Call* expr,
8244 int arguments_count) { 8227 int arguments_count) {
8245 return TryInline(CALL_AS_METHOD, 8228 return TryInline(CALL_AS_METHOD,
8246 function, 8229 function,
8247 arguments_count, 8230 arguments_count,
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
8822 8805
8823 call->set_position(expr->position()); 8806 call->set_position(expr->position());
8824 return ast_context()->ReturnInstruction(call, expr->id()); 8807 return ast_context()->ReturnInstruction(call, expr->id());
8825 } 8808 }
8826 8809
8827 8810
8828 // Checks whether allocation using the given constructor can be inlined. 8811 // Checks whether allocation using the given constructor can be inlined.
8829 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { 8812 static bool IsAllocationInlineable(Handle<JSFunction> constructor) {
8830 return constructor->has_initial_map() && 8813 return constructor->has_initial_map() &&
8831 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && 8814 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
8832 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && 8815 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize;
8833 constructor->initial_map()->InitialPropertiesLength() == 0;
8834 } 8816 }
8835 8817
8836 8818
8837 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 8819 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
8838 ASSERT(!HasStackOverflow()); 8820 ASSERT(!HasStackOverflow());
8839 ASSERT(current_block() != NULL); 8821 ASSERT(current_block() != NULL);
8840 ASSERT(current_block()->HasPredecessor()); 8822 ASSERT(current_block()->HasPredecessor());
8841 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 8823 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
8842 HValue* context = environment()->LookupContext(); 8824 HValue* context = environment()->LookupContext();
8843 Factory* factory = isolate()->factory();
8844 8825
8845 if (FLAG_inline_construct && 8826 if (FLAG_inline_construct &&
8846 expr->IsMonomorphic() && 8827 expr->IsMonomorphic() &&
8847 IsAllocationInlineable(expr->target())) { 8828 IsAllocationInlineable(expr->target())) {
8848 // The constructor function is on the stack in the unoptimized code 8829 // The constructor function is on the stack in the unoptimized code
8849 // during evaluation of the arguments. 8830 // during evaluation of the arguments.
8850 CHECK_ALIVE(VisitForValue(expr->expression())); 8831 CHECK_ALIVE(VisitForValue(expr->expression()));
8851 HValue* function = Top(); 8832 HValue* function = Top();
8852 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8833 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8853 Handle<JSFunction> constructor = expr->target(); 8834 Handle<JSFunction> constructor = expr->target();
8854 HValue* check = AddInstruction( 8835 HValue* check = AddInstruction(
8855 new(zone()) HCheckFunction(function, constructor)); 8836 new(zone()) HCheckFunction(function, constructor));
8856 8837
8857 // Force completion of inobject slack tracking before generating 8838 // Force completion of inobject slack tracking before generating
8858 // allocation code to finalize instance size. 8839 // allocation code to finalize instance size.
8859 if (constructor->shared()->IsInobjectSlackTrackingInProgress()) { 8840 if (constructor->shared()->IsInobjectSlackTrackingInProgress()) {
8860 constructor->shared()->CompleteInobjectSlackTracking(); 8841 constructor->shared()->CompleteInobjectSlackTracking();
8861 } 8842 }
8862 8843
8863 // Calculate instance size from initial map of constructor. 8844 // Replace the constructor function with a newly allocated receiver.
8864 ASSERT(constructor->has_initial_map()); 8845 HInstruction* receiver = new(zone()) HAllocateObject(context, constructor);
8865 Handle<Map> initial_map(constructor->initial_map()); 8846 // Index of the receiver from the top of the expression stack.
8866 int instance_size = initial_map->instance_size();
8867 ASSERT(initial_map->InitialPropertiesLength() == 0);
8868
8869 // Allocate an instance of the implicit receiver object.
8870 HValue* size_in_bytes =
8871 AddInstruction(new(zone()) HConstant(instance_size));
8872
8873 HAllocate::Flags flags = HAllocate::DefaultFlags();
8874 if (FLAG_pretenuring_call_new &&
8875 isolate()->heap()->ShouldGloballyPretenure()) {
8876 flags = static_cast<HAllocate::Flags>(
8877 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
8878 }
8879
8880 HInstruction* receiver =
8881 AddInstruction(new(zone()) HAllocate(context,
8882 size_in_bytes,
8883 HType::JSObject(),
8884 flags));
8885 HAllocate::cast(receiver)->set_known_initial_map(initial_map);
8886
8887 // Load the initial map from the constructor.
8888 HValue* constructor_value =
8889 AddInstruction(new(zone()) HConstant(constructor));
8890 HValue* initial_map_value =
8891 AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset(
8892 JSFunction::kPrototypeOrInitialMapOffset));
8893
8894 // Initialize map and fields of the newly allocated object.
8895 { NoObservableSideEffectsScope no_effects(this);
8896 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
8897 AddStore(receiver,
8898 HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
8899 initial_map_value);
8900 HValue* empty_fixed_array =
8901 AddInstruction(new(zone()) HConstant(factory->empty_fixed_array()));
8902 AddStore(receiver,
8903 HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
8904 empty_fixed_array);
8905 AddStore(receiver,
8906 HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
8907 empty_fixed_array);
8908 if (initial_map->inobject_properties() != 0) {
8909 HConstant* undefined = graph()->GetConstantUndefined();
8910 for (int i = 0; i < initial_map->inobject_properties(); i++) {
8911 int property_offset = JSObject::kHeaderSize + i * kPointerSize;
8912 AddStore(receiver,
8913 HObjectAccess::ForJSObjectOffset(property_offset),
8914 undefined);
8915 }
8916 }
8917 }
8918
8919 // Replace the constructor function with a newly allocated receiver using
8920 // the index of the receiver from the top of the expression stack.
8921 const int receiver_index = argument_count - 1; 8847 const int receiver_index = argument_count - 1;
8848 AddInstruction(receiver);
8922 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); 8849 ASSERT(environment()->ExpressionStackAt(receiver_index) == function);
8923 environment()->SetExpressionStackAt(receiver_index, receiver); 8850 environment()->SetExpressionStackAt(receiver_index, receiver);
8924 8851
8925 if (TryInlineConstruct(expr, receiver)) return; 8852 if (TryInlineConstruct(expr, receiver)) return;
8926 8853
8927 // TODO(mstarzinger): For now we remove the previous HAllocate and all 8854 // TODO(mstarzinger): For now we remove the previous HAllocateObject and
8928 // corresponding instructions and instead add HPushArgument for the 8855 // add HPushArgument for the arguments in case inlining failed. What we
8929 // arguments in case inlining failed. What we actually should do is for 8856 // actually should do is emit HInvokeFunction on the constructor instead
8930 // inlining to try to build a subgraph without mutating the parent graph. 8857 // of using HCallNew as a fallback.
8931 HInstruction* instr = current_block()->last();
8932 while (instr != initial_map_value) {
8933 HInstruction* prev_instr = instr->previous();
8934 instr->DeleteAndReplaceWith(NULL);
8935 instr = prev_instr;
8936 }
8937 initial_map_value->DeleteAndReplaceWith(NULL);
8938 receiver->DeleteAndReplaceWith(NULL); 8858 receiver->DeleteAndReplaceWith(NULL);
8939 check->DeleteAndReplaceWith(NULL); 8859 check->DeleteAndReplaceWith(NULL);
8940 environment()->SetExpressionStackAt(receiver_index, function); 8860 environment()->SetExpressionStackAt(receiver_index, function);
8941 HInstruction* call = PreProcessCall( 8861 HInstruction* call = PreProcessCall(
8942 new(zone()) HCallNew(context, function, argument_count)); 8862 new(zone()) HCallNew(context, function, argument_count));
8943 call->set_position(expr->position()); 8863 call->set_position(expr->position());
8944 return ast_context()->ReturnInstruction(call, expr->id()); 8864 return ast_context()->ReturnInstruction(call, expr->id());
8945 } else { 8865 } else {
8946 // The constructor function is both an operand to the instruction and an 8866 // The constructor function is both an operand to the instruction and an
8947 // argument to the construct call. 8867 // argument to the construct call.
8948 Handle<JSFunction> array_function = 8868 Handle<JSFunction> array_function(
8949 Handle<JSFunction>(isolate()->global_context()->array_function(), 8869 isolate()->global_context()->array_function(), isolate());
8950 isolate());
8951 bool use_call_new_array = FLAG_optimize_constructed_arrays &&
8952 expr->target().is_identical_to(array_function);
8953
8954 CHECK_ALIVE(VisitArgument(expr->expression())); 8870 CHECK_ALIVE(VisitArgument(expr->expression()));
8955 HValue* constructor = HPushArgument::cast(Top())->argument(); 8871 HValue* constructor = HPushArgument::cast(Top())->argument();
8956 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 8872 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
8957 HCallNew* call; 8873 HCallNew* call;
8958 if (use_call_new_array) { 8874 if (expr->target().is_identical_to(array_function)) {
8959 Handle<Cell> cell = expr->allocation_info_cell(); 8875 Handle<Cell> cell = expr->allocation_info_cell();
8960 AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); 8876 AddInstruction(new(zone()) HCheckFunction(constructor, array_function));
8961 call = new(zone()) HCallNewArray(context, constructor, argument_count, 8877 call = new(zone()) HCallNewArray(context, constructor, argument_count,
8962 cell); 8878 cell);
8963 } else { 8879 } else {
8964 call = new(zone()) HCallNew(context, constructor, argument_count); 8880 call = new(zone()) HCallNew(context, constructor, argument_count);
8965 } 8881 }
8966 Drop(argument_count); 8882 Drop(argument_count);
8967 call->set_position(expr->position()); 8883 call->set_position(expr->position());
8968 return ast_context()->ReturnInstruction(call, expr->id()); 8884 return ast_context()->ReturnInstruction(call, expr->id());
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
9089 return ast_context()->ReturnInstruction(instr, expr->id()); 9005 return ast_context()->ReturnInstruction(instr, expr->id());
9090 } 9006 }
9091 9007
9092 9008
9093 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) { 9009 void HOptimizedGraphBuilder::VisitSub(UnaryOperation* expr) {
9094 CHECK_ALIVE(VisitForValue(expr->expression())); 9010 CHECK_ALIVE(VisitForValue(expr->expression()));
9095 HValue* value = Pop(); 9011 HValue* value = Pop();
9096 HValue* context = environment()->LookupContext(); 9012 HValue* context = environment()->LookupContext();
9097 HInstruction* instr = 9013 HInstruction* instr =
9098 HMul::New(zone(), context, value, graph()->GetConstantMinus1()); 9014 HMul::New(zone(), context, value, graph()->GetConstantMinus1());
9099 Handle<Type> type = expr->type(); 9015 Handle<Type> operand_type = expr->expression()->lower_type();
9100 Representation rep = ToRepresentation(type); 9016 Representation rep = ToRepresentation(operand_type);
9101 if (type->Is(Type::None())) { 9017 if (operand_type->Is(Type::None())) {
9102 AddSoftDeoptimize(); 9018 AddSoftDeoptimize();
9103 type = handle(Type::Any(), isolate());
9104 } 9019 }
9105 if (instr->IsBinaryOperation()) { 9020 if (instr->IsBinaryOperation()) {
9106 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep); 9021 HBinaryOperation::cast(instr)->set_observed_input_representation(1, rep);
9107 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep); 9022 HBinaryOperation::cast(instr)->set_observed_input_representation(2, rep);
9108 } 9023 }
9109 return ast_context()->ReturnInstruction(instr, expr->id()); 9024 return ast_context()->ReturnInstruction(instr, expr->id());
9110 } 9025 }
9111 9026
9112 9027
9113 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) { 9028 void HOptimizedGraphBuilder::VisitBitNot(UnaryOperation* expr) {
9114 CHECK_ALIVE(VisitForValue(expr->expression())); 9029 CHECK_ALIVE(VisitForValue(expr->expression()));
9115 HValue* value = Pop(); 9030 HValue* value = Pop();
9116 Handle<Type> info = expr->type(); 9031 Handle<Type> operand_type = expr->expression()->lower_type();
9117 if (info->Is(Type::None())) { 9032 if (operand_type->Is(Type::None())) {
9118 AddSoftDeoptimize(); 9033 AddSoftDeoptimize();
9119 } 9034 }
9120 HInstruction* instr = new(zone()) HBitNot(value); 9035 HInstruction* instr = new(zone()) HBitNot(value);
9121 return ast_context()->ReturnInstruction(instr, expr->id()); 9036 return ast_context()->ReturnInstruction(instr, expr->id());
9122 } 9037 }
9123 9038
9124 9039
9125 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) { 9040 void HOptimizedGraphBuilder::VisitNot(UnaryOperation* expr) {
9126 if (ast_context()->IsTest()) { 9041 if (ast_context()->IsTest()) {
9127 TestContext* context = TestContext::cast(ast_context()); 9042 TestContext* context = TestContext::cast(ast_context());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
9165 if (join != NULL) return ast_context()->ReturnValue(Pop()); 9080 if (join != NULL) return ast_context()->ReturnValue(Pop());
9166 } 9081 }
9167 9082
9168 9083
9169 HInstruction* HOptimizedGraphBuilder::BuildIncrement( 9084 HInstruction* HOptimizedGraphBuilder::BuildIncrement(
9170 bool returns_original_input, 9085 bool returns_original_input,
9171 CountOperation* expr) { 9086 CountOperation* expr) {
9172 // The input to the count operation is on top of the expression stack. 9087 // The input to the count operation is on top of the expression stack.
9173 TypeInfo info = expr->type(); 9088 TypeInfo info = expr->type();
9174 Representation rep = ToRepresentation(info); 9089 Representation rep = ToRepresentation(info);
9175 if (rep.IsTagged()) { 9090 if (rep.IsNone() || rep.IsTagged()) {
9176 rep = Representation::Integer32(); 9091 rep = Representation::Smi();
9177 } 9092 }
9178 9093
9179 if (returns_original_input) { 9094 if (returns_original_input) {
9180 // We need an explicit HValue representing ToNumber(input). The 9095 // We need an explicit HValue representing ToNumber(input). The
9181 // actual HChange instruction we need is (sometimes) added in a later 9096 // actual HChange instruction we need is (sometimes) added in a later
9182 // phase, so it is not available now to be used as an input to HAdd and 9097 // phase, so it is not available now to be used as an input to HAdd and
9183 // as the return value. 9098 // as the return value.
9184 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep); 9099 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep);
9100 if (!rep.IsDouble()) {
9101 number_input->SetFlag(HInstruction::kFlexibleRepresentation);
9102 number_input->SetFlag(HInstruction::kCannotBeTagged);
9103 }
9185 AddInstruction(number_input); 9104 AddInstruction(number_input);
9186 Push(number_input); 9105 Push(number_input);
9187 } 9106 }
9188 9107
9189 // The addition has no side effects, so we do not need 9108 // The addition has no side effects, so we do not need
9190 // to simulate the expression stack after this instruction. 9109 // to simulate the expression stack after this instruction.
9191 // Any later failures deopt to the load of the input or earlier. 9110 // Any later failures deopt to the load of the input or earlier.
9192 HConstant* delta = (expr->op() == Token::INC) 9111 HConstant* delta = (expr->op() == Token::INC)
9193 ? graph()->GetConstant1() 9112 ? graph()->GetConstant1()
9194 : graph()->GetConstantMinus1(); 9113 : graph()->GetConstantMinus1();
9195 HValue* context = environment()->LookupContext(); 9114 HValue* context = environment()->LookupContext();
9196 HInstruction* instr = HAdd::New(zone(), context, Top(), delta); 9115 HInstruction* instr = HAdd::New(zone(), context, Top(), delta);
9197 // We can't insert a simulate here, because it would break deoptimization, 9116 instr->SetFlag(HInstruction::kCannotBeTagged);
9198 // so the HAdd must not have side effects, so we must freeze its
9199 // representation.
9200 instr->AssumeRepresentation(rep);
9201 instr->ClearAllSideEffects(); 9117 instr->ClearAllSideEffects();
9202 AddInstruction(instr); 9118 AddInstruction(instr);
9203 return instr; 9119 return instr;
9204 } 9120 }
9205 9121
9206 9122
9207 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 9123 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
9208 ASSERT(!HasStackOverflow()); 9124 ASSERT(!HasStackOverflow());
9209 ASSERT(current_block() != NULL); 9125 ASSERT(current_block() != NULL);
9210 ASSERT(current_block()->HasPredecessor()); 9126 ASSERT(current_block()->HasPredecessor());
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
9398 HConstant* c_index = HConstant::cast(index); 9314 HConstant* c_index = HConstant::cast(index);
9399 if (c_string->HasStringValue() && c_index->HasNumberValue()) { 9315 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
9400 int32_t i = c_index->NumberValueAsInteger32(); 9316 int32_t i = c_index->NumberValueAsInteger32();
9401 Handle<String> s = c_string->StringValue(); 9317 Handle<String> s = c_string->StringValue();
9402 if (i < 0 || i >= s->length()) { 9318 if (i < 0 || i >= s->length()) {
9403 return new(zone()) HConstant(OS::nan_value()); 9319 return new(zone()) HConstant(OS::nan_value());
9404 } 9320 }
9405 return new(zone()) HConstant(s->Get(i)); 9321 return new(zone()) HConstant(s->Get(i));
9406 } 9322 }
9407 } 9323 }
9408 BuildCheckNonSmi(string); 9324 BuildCheckHeapObject(string);
9409 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); 9325 AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
9410 HInstruction* length = HStringLength::New(zone(), string); 9326 HInstruction* length = HStringLength::New(zone(), string);
9411 AddInstruction(length); 9327 AddInstruction(length);
9412 HInstruction* checked_index = AddBoundsCheck(index, length); 9328 HInstruction* checked_index = AddBoundsCheck(index, length);
9413 return new(zone()) HStringCharCodeAt(context, string, checked_index); 9329 return new(zone()) HStringCharCodeAt(context, string, checked_index);
9414 } 9330 }
9415 9331
9416 // Checks if the given shift amounts have form: (sa) and (32 - sa). 9332 // Checks if the given shift amounts have form: (sa) and (32 - sa).
9417 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 9333 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
9418 HValue* const32_minus_sa) { 9334 HValue* const32_minus_sa) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
9469 } 9385 }
9470 return true; 9386 return true;
9471 } 9387 }
9472 9388
9473 9389
9474 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 9390 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
9475 BinaryOperation* expr, 9391 BinaryOperation* expr,
9476 HValue* left, 9392 HValue* left,
9477 HValue* right) { 9393 HValue* right) {
9478 HValue* context = environment()->LookupContext(); 9394 HValue* context = environment()->LookupContext();
9479 Handle<Type> left_type = expr->left_type(); 9395 Handle<Type> left_type = expr->left()->lower_type();
9480 Handle<Type> right_type = expr->right_type(); 9396 Handle<Type> right_type = expr->right()->lower_type();
9481 Handle<Type> result_type = expr->result_type(); 9397 Handle<Type> result_type = expr->lower_type();
9482 bool has_fixed_right_arg = expr->has_fixed_right_arg(); 9398 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
9483 int fixed_right_arg_value = expr->fixed_right_arg_value();
9484 Representation left_rep = ToRepresentation(left_type); 9399 Representation left_rep = ToRepresentation(left_type);
9485 Representation right_rep = ToRepresentation(right_type); 9400 Representation right_rep = ToRepresentation(right_type);
9486 Representation result_rep = ToRepresentation(result_type); 9401 Representation result_rep = ToRepresentation(result_type);
9487 if (left_type->Is(Type::None())) { 9402 if (left_type->Is(Type::None())) {
9488 AddSoftDeoptimize(); 9403 AddSoftDeoptimize();
9404 // TODO(rossberg): we should be able to get rid of non-continuous defaults.
9489 left_type = handle(Type::Any(), isolate()); 9405 left_type = handle(Type::Any(), isolate());
9490 } 9406 }
9491 if (right_type->Is(Type::None())) { 9407 if (right_type->Is(Type::None())) {
9492 AddSoftDeoptimize(); 9408 AddSoftDeoptimize();
9493 right_type = handle(Type::Any(), isolate()); 9409 right_type = handle(Type::Any(), isolate());
9494 } 9410 }
9495 HInstruction* instr = NULL; 9411 HInstruction* instr = NULL;
9496 switch (expr->op()) { 9412 switch (expr->op()) {
9497 case Token::ADD: 9413 case Token::ADD:
9498 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { 9414 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
9499 BuildCheckNonSmi(left); 9415 BuildCheckHeapObject(left);
9500 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 9416 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
9501 BuildCheckNonSmi(right); 9417 BuildCheckHeapObject(right);
9502 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 9418 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
9503 instr = HStringAdd::New(zone(), context, left, right); 9419 instr = HStringAdd::New(zone(), context, left, right);
9504 } else { 9420 } else {
9505 instr = HAdd::New(zone(), context, left, right); 9421 instr = HAdd::New(zone(), context, left, right);
9506 } 9422 }
9507 break; 9423 break;
9508 case Token::SUB: 9424 case Token::SUB:
9509 instr = HSub::New(zone(), context, left, right); 9425 instr = HSub::New(zone(), context, left, right);
9510 break; 9426 break;
9511 case Token::MUL: 9427 case Token::MUL:
9512 instr = HMul::New(zone(), context, left, right); 9428 instr = HMul::New(zone(), context, left, right);
9513 break; 9429 break;
9514 case Token::MOD: 9430 case Token::MOD:
9515 instr = HMod::New(zone(), 9431 instr = HMod::New(zone(), context, left, right, fixed_right_arg);
9516 context,
9517 left,
9518 right,
9519 has_fixed_right_arg,
9520 fixed_right_arg_value);
9521 break; 9432 break;
9522 case Token::DIV: 9433 case Token::DIV:
9523 instr = HDiv::New(zone(), context, left, right); 9434 instr = HDiv::New(zone(), context, left, right);
9524 break; 9435 break;
9525 case Token::BIT_XOR: 9436 case Token::BIT_XOR:
9526 case Token::BIT_AND: 9437 case Token::BIT_AND:
9527 instr = HBitwise::New(zone(), expr->op(), context, left, right); 9438 instr = HBitwise::New(zone(), expr->op(), context, left, right);
9528 break; 9439 break;
9529 case Token::BIT_OR: { 9440 case Token::BIT_OR: {
9530 HValue* operand, *shift_amount; 9441 HValue* operand, *shift_amount;
9531 if (left_type->Is(Type::Integer32()) && 9442 if (left_type->Is(Type::Signed32()) &&
9532 right_type->Is(Type::Integer32()) && 9443 right_type->Is(Type::Signed32()) &&
9533 MatchRotateRight(left, right, &operand, &shift_amount)) { 9444 MatchRotateRight(left, right, &operand, &shift_amount)) {
9534 instr = new(zone()) HRor(context, operand, shift_amount); 9445 instr = new(zone()) HRor(context, operand, shift_amount);
9535 } else { 9446 } else {
9536 instr = HBitwise::New(zone(), expr->op(), context, left, right); 9447 instr = HBitwise::New(zone(), expr->op(), context, left, right);
9537 } 9448 }
9538 break; 9449 break;
9539 } 9450 }
9540 case Token::SAR: 9451 case Token::SAR:
9541 instr = HSar::New(zone(), context, left, right); 9452 instr = HSar::New(zone(), context, left, right);
9542 break; 9453 break;
(...skipping 21 matching lines...) Expand all
9564 } 9475 }
9565 9476
9566 9477
9567 // Check for the form (%_ClassOf(foo) === 'BarClass'). 9478 // Check for the form (%_ClassOf(foo) === 'BarClass').
9568 static bool IsClassOfTest(CompareOperation* expr) { 9479 static bool IsClassOfTest(CompareOperation* expr) {
9569 if (expr->op() != Token::EQ_STRICT) return false; 9480 if (expr->op() != Token::EQ_STRICT) return false;
9570 CallRuntime* call = expr->left()->AsCallRuntime(); 9481 CallRuntime* call = expr->left()->AsCallRuntime();
9571 if (call == NULL) return false; 9482 if (call == NULL) return false;
9572 Literal* literal = expr->right()->AsLiteral(); 9483 Literal* literal = expr->right()->AsLiteral();
9573 if (literal == NULL) return false; 9484 if (literal == NULL) return false;
9574 if (!literal->handle()->IsString()) return false; 9485 if (!literal->value()->IsString()) return false;
9575 if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) { 9486 if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) {
9576 return false; 9487 return false;
9577 } 9488 }
9578 ASSERT(call->arguments()->length() == 1); 9489 ASSERT(call->arguments()->length() == 1);
9579 return true; 9490 return true;
9580 } 9491 }
9581 9492
9582 9493
9583 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 9494 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
9584 ASSERT(!HasStackOverflow()); 9495 ASSERT(!HasStackOverflow());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
9722 if (info.IsSmi()) return Representation::Integer32(); 9633 if (info.IsSmi()) return Representation::Integer32();
9723 if (info.IsInteger32()) return Representation::Integer32(); 9634 if (info.IsInteger32()) return Representation::Integer32();
9724 if (info.IsDouble()) return Representation::Double(); 9635 if (info.IsDouble()) return Representation::Double();
9725 if (info.IsNumber()) return Representation::Double(); 9636 if (info.IsNumber()) return Representation::Double();
9726 return Representation::Tagged(); 9637 return Representation::Tagged();
9727 } 9638 }
9728 9639
9729 9640
9730 Representation HOptimizedGraphBuilder::ToRepresentation(Handle<Type> type) { 9641 Representation HOptimizedGraphBuilder::ToRepresentation(Handle<Type> type) {
9731 if (type->Is(Type::None())) return Representation::None(); 9642 if (type->Is(Type::None())) return Representation::None();
9732 if (type->Is(Type::Integer32())) return Representation::Integer32(); 9643 if (type->Is(Type::Signed32())) return Representation::Integer32();
9733 if (type->Is(Type::Number())) return Representation::Double(); 9644 if (type->Is(Type::Number())) return Representation::Double();
9734 return Representation::Tagged(); 9645 return Representation::Tagged();
9735 } 9646 }
9736 9647
9737 9648
9738 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 9649 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
9739 HTypeof* typeof_expr, 9650 HTypeof* typeof_expr,
9740 Handle<String> check) { 9651 Handle<String> check) {
9741 // Note: The HTypeof itself is removed during canonicalization, if possible. 9652 // Note: The HTypeof itself is removed during canonicalization, if possible.
9742 HValue* value = typeof_expr->value(); 9653 HValue* value = typeof_expr->value();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
9810 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 9721 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
9811 ASSERT(!HasStackOverflow()); 9722 ASSERT(!HasStackOverflow());
9812 ASSERT(current_block() != NULL); 9723 ASSERT(current_block() != NULL);
9813 ASSERT(current_block()->HasPredecessor()); 9724 ASSERT(current_block()->HasPredecessor());
9814 if (IsClassOfTest(expr)) { 9725 if (IsClassOfTest(expr)) {
9815 CallRuntime* call = expr->left()->AsCallRuntime(); 9726 CallRuntime* call = expr->left()->AsCallRuntime();
9816 ASSERT(call->arguments()->length() == 1); 9727 ASSERT(call->arguments()->length() == 1);
9817 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9728 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9818 HValue* value = Pop(); 9729 HValue* value = Pop();
9819 Literal* literal = expr->right()->AsLiteral(); 9730 Literal* literal = expr->right()->AsLiteral();
9820 Handle<String> rhs = Handle<String>::cast(literal->handle()); 9731 Handle<String> rhs = Handle<String>::cast(literal->value());
9821 HClassOfTestAndBranch* instr = 9732 HClassOfTestAndBranch* instr =
9822 new(zone()) HClassOfTestAndBranch(value, rhs); 9733 new(zone()) HClassOfTestAndBranch(value, rhs);
9823 instr->set_position(expr->position()); 9734 instr->set_position(expr->position());
9824 return ast_context()->ReturnControl(instr, expr->id()); 9735 return ast_context()->ReturnControl(instr, expr->id());
9825 } 9736 }
9826 9737
9827 Handle<Type> left_type = expr->left_type(); 9738 Handle<Type> left_type = expr->left()->lower_type();
9828 Handle<Type> right_type = expr->right_type(); 9739 Handle<Type> right_type = expr->right()->lower_type();
9829 Handle<Type> overall_type = expr->overall_type(); 9740 Handle<Type> combined_type = expr->combined_type();
9830 Representation combined_rep = ToRepresentation(overall_type); 9741 Representation combined_rep = ToRepresentation(combined_type);
9831 Representation left_rep = ToRepresentation(left_type); 9742 Representation left_rep = ToRepresentation(left_type);
9832 Representation right_rep = ToRepresentation(right_type); 9743 Representation right_rep = ToRepresentation(right_type);
9833 // Check if this expression was ever executed according to type feedback. 9744 // Check if this expression was ever executed according to type feedback.
9834 // Note that for the special typeof/null/undefined cases we get unknown here. 9745 // Note that for the special typeof/null/undefined cases we get unknown here.
9835 if (overall_type->Is(Type::None())) { 9746 if (combined_type->Is(Type::None())) {
9836 AddSoftDeoptimize(); 9747 AddSoftDeoptimize();
9837 overall_type = left_type = right_type = handle(Type::Any(), isolate()); 9748 combined_type = left_type = right_type = handle(Type::Any(), isolate());
9838 } 9749 }
9839 9750
9840 CHECK_ALIVE(VisitForValue(expr->left())); 9751 CHECK_ALIVE(VisitForValue(expr->left()));
9841 CHECK_ALIVE(VisitForValue(expr->right())); 9752 CHECK_ALIVE(VisitForValue(expr->right()));
9842 9753
9843 HValue* context = environment()->LookupContext(); 9754 HValue* context = environment()->LookupContext();
9844 HValue* right = Pop(); 9755 HValue* right = Pop();
9845 HValue* left = Pop(); 9756 HValue* left = Pop();
9846 Token::Value op = expr->op(); 9757 Token::Value op = expr->op();
9847 9758
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
9899 AddInstruction(new(zone()) HCheckFunction(right, target)); 9810 AddInstruction(new(zone()) HCheckFunction(right, target));
9900 HInstanceOfKnownGlobal* result = 9811 HInstanceOfKnownGlobal* result =
9901 new(zone()) HInstanceOfKnownGlobal(context, left, target); 9812 new(zone()) HInstanceOfKnownGlobal(context, left, target);
9902 result->set_position(expr->position()); 9813 result->set_position(expr->position());
9903 return ast_context()->ReturnInstruction(result, expr->id()); 9814 return ast_context()->ReturnInstruction(result, expr->id());
9904 } 9815 }
9905 } else if (op == Token::IN) { 9816 } else if (op == Token::IN) {
9906 HIn* result = new(zone()) HIn(context, left, right); 9817 HIn* result = new(zone()) HIn(context, left, right);
9907 result->set_position(expr->position()); 9818 result->set_position(expr->position());
9908 return ast_context()->ReturnInstruction(result, expr->id()); 9819 return ast_context()->ReturnInstruction(result, expr->id());
9909 } else if (overall_type->Is(Type::Receiver())) { 9820 } else if (combined_type->Is(Type::Receiver())) {
9910 switch (op) { 9821 switch (op) {
9911 case Token::EQ: 9822 case Token::EQ:
9912 case Token::EQ_STRICT: { 9823 case Token::EQ_STRICT: {
9913 // Can we get away with map check and not instance type check? 9824 // Can we get away with map check and not instance type check?
9914 if (overall_type->IsClass()) { 9825 if (combined_type->IsClass()) {
9915 Handle<Map> map = overall_type->AsClass(); 9826 Handle<Map> map = combined_type->AsClass();
9916 AddCheckMapsWithTransitions(left, map); 9827 AddCheckMapsWithTransitions(left, map);
9917 AddCheckMapsWithTransitions(right, map); 9828 AddCheckMapsWithTransitions(right, map);
9918 HCompareObjectEqAndBranch* result = 9829 HCompareObjectEqAndBranch* result =
9919 new(zone()) HCompareObjectEqAndBranch(left, right); 9830 new(zone()) HCompareObjectEqAndBranch(left, right);
9920 result->set_position(expr->position()); 9831 result->set_position(expr->position());
9921 return ast_context()->ReturnControl(result, expr->id()); 9832 return ast_context()->ReturnControl(result, expr->id());
9922 } else { 9833 } else {
9923 BuildCheckNonSmi(left); 9834 BuildCheckHeapObject(left);
9924 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 9835 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
9925 BuildCheckNonSmi(right); 9836 BuildCheckHeapObject(right);
9926 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 9837 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
9927 HCompareObjectEqAndBranch* result = 9838 HCompareObjectEqAndBranch* result =
9928 new(zone()) HCompareObjectEqAndBranch(left, right); 9839 new(zone()) HCompareObjectEqAndBranch(left, right);
9929 result->set_position(expr->position()); 9840 result->set_position(expr->position());
9930 return ast_context()->ReturnControl(result, expr->id()); 9841 return ast_context()->ReturnControl(result, expr->id());
9931 } 9842 }
9932 } 9843 }
9933 default: 9844 default:
9934 return Bailout("Unsupported non-primitive compare"); 9845 return Bailout("Unsupported non-primitive compare");
9935 } 9846 }
9936 } else if (overall_type->Is(Type::InternalizedString()) && 9847 } else if (combined_type->Is(Type::InternalizedString()) &&
9937 Token::IsEqualityOp(op)) { 9848 Token::IsEqualityOp(op)) {
9938 BuildCheckNonSmi(left); 9849 BuildCheckHeapObject(left);
9939 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone())); 9850 AddInstruction(HCheckInstanceType::NewIsInternalizedString(left, zone()));
9940 BuildCheckNonSmi(right); 9851 BuildCheckHeapObject(right);
9941 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone())); 9852 AddInstruction(HCheckInstanceType::NewIsInternalizedString(right, zone()));
9942 HCompareObjectEqAndBranch* result = 9853 HCompareObjectEqAndBranch* result =
9943 new(zone()) HCompareObjectEqAndBranch(left, right); 9854 new(zone()) HCompareObjectEqAndBranch(left, right);
9944 result->set_position(expr->position()); 9855 result->set_position(expr->position());
9945 return ast_context()->ReturnControl(result, expr->id()); 9856 return ast_context()->ReturnControl(result, expr->id());
9946 } else { 9857 } else {
9947 if (combined_rep.IsTagged() || combined_rep.IsNone()) { 9858 if (combined_rep.IsTagged() || combined_rep.IsNone()) {
9948 HCompareGeneric* result = 9859 HCompareGeneric* result =
9949 new(zone()) HCompareGeneric(context, left, right, op); 9860 new(zone()) HCompareGeneric(context, left, right, op);
9950 result->set_observed_input_representation(1, left_rep); 9861 result->set_observed_input_representation(1, left_rep);
9951 result->set_observed_input_representation(2, right_rep); 9862 result->set_observed_input_representation(2, right_rep);
9952 result->set_position(expr->position()); 9863 result->set_position(expr->position());
9953 return ast_context()->ReturnInstruction(result, expr->id()); 9864 return ast_context()->ReturnInstruction(result, expr->id());
9954 } else { 9865 } else {
9955 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when 9866 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when
9956 // the IC measures Smi. 9867 // the IC measures Smi.
9957 if (left_type->Is(Type::Integer31())) left_rep = Representation::Smi(); 9868 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi();
9958 if (right_type->Is(Type::Integer31())) right_rep = Representation::Smi(); 9869 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi();
9959 HCompareIDAndBranch* result = 9870 HCompareIDAndBranch* result =
9960 new(zone()) HCompareIDAndBranch(left, right, op); 9871 new(zone()) HCompareIDAndBranch(left, right, op);
9961 result->set_observed_input_representation(left_rep, right_rep); 9872 result->set_observed_input_representation(left_rep, right_rep);
9962 result->set_position(expr->position()); 9873 result->set_position(expr->position());
9963 return ast_context()->ReturnControl(result, expr->id()); 9874 return ast_context()->ReturnControl(result, expr->id());
9964 } 9875 }
9965 } 9876 }
9966 } 9877 }
9967 9878
9968 9879
9969 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 9880 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
9970 HValue* value, 9881 HValue* value,
9971 NilValue nil) { 9882 NilValue nil) {
9972 ASSERT(!HasStackOverflow()); 9883 ASSERT(!HasStackOverflow());
9973 ASSERT(current_block() != NULL); 9884 ASSERT(current_block() != NULL);
9974 ASSERT(current_block()->HasPredecessor()); 9885 ASSERT(current_block()->HasPredecessor());
9975 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 9886 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
9976 HIfContinuation continuation; 9887 HIfContinuation continuation;
9977 if (expr->op() == Token::EQ_STRICT) { 9888 if (expr->op() == Token::EQ_STRICT) {
9978 IfBuilder if_nil(this); 9889 IfBuilder if_nil(this);
9979 if_nil.If<HCompareObjectEqAndBranch>( 9890 if_nil.If<HCompareObjectEqAndBranch>(
9980 value, (nil == kNullValue) ? graph()->GetConstantNull() 9891 value, (nil == kNullValue) ? graph()->GetConstantNull()
9981 : graph()->GetConstantUndefined()); 9892 : graph()->GetConstantUndefined());
9982 if_nil.Then(); 9893 if_nil.Then();
9983 if_nil.Else(); 9894 if_nil.Else();
9984 if_nil.CaptureContinuation(&continuation); 9895 if_nil.CaptureContinuation(&continuation);
9985 return ast_context()->ReturnContinuation(&continuation, expr->id()); 9896 return ast_context()->ReturnContinuation(&continuation, expr->id());
9986 } 9897 }
9987 Handle<Type> type = expr->compare_nil_type()->Is(Type::None()) 9898 Handle<Type> type = expr->combined_type()->Is(Type::None())
9988 ? handle(Type::Any(), isolate_) : expr->compare_nil_type(); 9899 ? handle(Type::Any(), isolate_) : expr->combined_type();
9989 BuildCompareNil(value, type, expr->position(), &continuation); 9900 BuildCompareNil(value, type, expr->position(), &continuation);
9990 return ast_context()->ReturnContinuation(&continuation, expr->id()); 9901 return ast_context()->ReturnContinuation(&continuation, expr->id());
9991 } 9902 }
9992 9903
9993 9904
9994 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 9905 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
9995 // If we share optimized code between different closures, the 9906 // If we share optimized code between different closures, the
9996 // this-function is not a constant, except inside an inlined body. 9907 // this-function is not a constant, except inside an inlined body.
9997 if (function_state()->outer() != NULL) { 9908 if (function_state()->outer() != NULL) {
9998 return new(zone()) HConstant( 9909 return new(zone()) HConstant(
9999 function_state()->compilation_info()->closure()); 9910 function_state()->compilation_info()->closure());
10000 } else { 9911 } else {
10001 return new(zone()) HThisFunction; 9912 return new(zone()) HThisFunction;
10002 } 9913 }
10003 } 9914 }
10004 9915
10005 9916
10006 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 9917 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
10007 HValue* context, 9918 HValue* context,
10008 Handle<JSObject> boilerplate_object, 9919 Handle<JSObject> boilerplate_object,
10009 Handle<JSObject> original_boilerplate_object, 9920 Handle<JSObject> original_boilerplate_object,
10010 int data_size, 9921 int data_size,
10011 int pointer_size, 9922 int pointer_size,
10012 AllocationSiteMode mode) { 9923 AllocationSiteMode mode) {
10013 Zone* zone = this->zone(); 9924 Zone* zone = this->zone();
10014 int total_size = data_size + pointer_size;
10015
10016 NoObservableSideEffectsScope no_effects(this); 9925 NoObservableSideEffectsScope no_effects(this);
10017 9926
10018 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; 9927 HInstruction* target = NULL;
10019 // TODO(hpayer): add support for old data space 9928 HInstruction* data_target = NULL;
10020 if (isolate()->heap()->ShouldGloballyPretenure() && 9929
10021 data_size == 0) { 9930 HAllocate::Flags flags = HAllocate::DefaultFlags();
10022 flags = static_cast<HAllocate::Flags>( 9931
10023 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 9932 if (isolate()->heap()->ShouldGloballyPretenure()) {
9933 if (data_size != 0) {
9934 HAllocate::Flags data_flags =
9935 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() |
9936 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
9937 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(data_size));
9938 data_target = AddInstruction(new(zone) HAllocate(
9939 context, size_in_bytes, HType::JSObject(), data_flags));
9940 Handle<Map> free_space_map = isolate()->factory()->free_space_map();
9941 AddStoreMapConstant(data_target, free_space_map);
9942 HObjectAccess access =
9943 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
9944 AddStore(data_target, access, size_in_bytes);
9945 }
9946 if (pointer_size != 0) {
9947 flags = static_cast<HAllocate::Flags>(
9948 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
9949 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(pointer_size));
9950 target = AddInstruction(new(zone) HAllocate(context,
9951 size_in_bytes, HType::JSObject(), flags));
9952 }
9953 } else {
9954 HValue* size_in_bytes =
9955 AddInstruction(new(zone) HConstant(data_size + pointer_size));
9956 target = AddInstruction(new(zone) HAllocate(context, size_in_bytes,
9957 HType::JSObject(), flags));
10024 } 9958 }
10025 9959
10026 HValue* size_in_bytes = AddInstruction(new(zone) HConstant(total_size));
10027 HInstruction* result =
10028 AddInstruction(new(zone) HAllocate(context,
10029 size_in_bytes,
10030 HType::JSObject(),
10031 flags));
10032 int offset = 0; 9960 int offset = 0;
10033 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, result, 9961 int data_offset = 0;
10034 &offset, mode); 9962 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, target,
10035 return result; 9963 &offset, data_target, &data_offset, mode);
9964 return target;
10036 } 9965 }
10037 9966
10038 9967
10039 void HOptimizedGraphBuilder::BuildEmitDeepCopy( 9968 void HOptimizedGraphBuilder::BuildEmitDeepCopy(
10040 Handle<JSObject> boilerplate_object, 9969 Handle<JSObject> boilerplate_object,
10041 Handle<JSObject> original_boilerplate_object, 9970 Handle<JSObject> original_boilerplate_object,
10042 HInstruction* target, 9971 HInstruction* target,
10043 int* offset, 9972 int* offset,
9973 HInstruction* data_target,
9974 int* data_offset,
10044 AllocationSiteMode mode) { 9975 AllocationSiteMode mode) {
10045 Zone* zone = this->zone(); 9976 Zone* zone = this->zone();
10046 9977
10047 Handle<FixedArrayBase> elements(boilerplate_object->elements()); 9978 Handle<FixedArrayBase> elements(boilerplate_object->elements());
10048 Handle<FixedArrayBase> original_elements( 9979 Handle<FixedArrayBase> original_elements(
10049 original_boilerplate_object->elements()); 9980 original_boilerplate_object->elements());
10050 ElementsKind kind = boilerplate_object->map()->elements_kind(); 9981 ElementsKind kind = boilerplate_object->map()->elements_kind();
10051 9982
10052 // Increase the offset so that subsequent objects end up right after
10053 // this object and its backing store.
10054 int object_offset = *offset; 9983 int object_offset = *offset;
10055 int object_size = boilerplate_object->map()->instance_size(); 9984 int object_size = boilerplate_object->map()->instance_size();
10056 int elements_size = (elements->length() > 0 && 9985 int elements_size = (elements->length() > 0 &&
10057 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? 9986 elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
10058 elements->Size() : 0; 9987 elements->Size() : 0;
10059 int elements_offset = *offset + object_size; 9988 int elements_offset = 0;
10060 9989
10061 *offset += object_size + elements_size; 9990 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
9991 elements_offset = *data_offset;
9992 *data_offset += elements_size;
9993 } else {
9994 // Place elements right after this object.
9995 elements_offset = *offset + object_size;
9996 *offset += elements_size;
9997 }
9998 // Increase the offset so that subsequent objects end up right after this
9999 // object (and it's elements if they are allocated in the same space).
10000 *offset += object_size;
10062 10001
10063 // Copy object elements if non-COW. 10002 // Copy object elements if non-COW.
10064 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target, 10003 HValue* object_elements = BuildEmitObjectHeader(boilerplate_object, target,
10065 object_offset, elements_offset, elements_size); 10004 data_target, object_offset, elements_offset, elements_size);
10066 if (object_elements != NULL) { 10005 if (object_elements != NULL) {
10067 BuildEmitElements(elements, original_elements, kind, object_elements, 10006 BuildEmitElements(elements, original_elements, kind, object_elements,
10068 target, offset); 10007 target, offset, data_target, data_offset);
10069 } 10008 }
10070 10009
10071 // Copy in-object properties. 10010 // Copy in-object properties.
10072 HValue* object_properties = 10011 HValue* object_properties =
10073 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10012 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10074 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, 10013 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object,
10075 object_properties, target, offset); 10014 object_properties, target, offset, data_target, data_offset);
10076 10015
10077 // Create allocation site info. 10016 // Create allocation site info.
10078 if (mode == TRACK_ALLOCATION_SITE && 10017 if (mode == TRACK_ALLOCATION_SITE &&
10079 boilerplate_object->map()->CanTrackAllocationSite()) { 10018 boilerplate_object->map()->CanTrackAllocationSite()) {
10080 elements_offset += AllocationSiteInfo::kSize; 10019 elements_offset += AllocationSiteInfo::kSize;
10081 *offset += AllocationSiteInfo::kSize; 10020 *offset += AllocationSiteInfo::kSize;
10082 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant( 10021 HInstruction* original_boilerplate = AddInstruction(new(zone) HConstant(
10083 original_boilerplate_object)); 10022 original_boilerplate_object));
10084 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); 10023 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate);
10085 } 10024 }
10086 } 10025 }
10087 10026
10088 10027
10089 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( 10028 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
10090 Handle<JSObject> boilerplate_object, 10029 Handle<JSObject> boilerplate_object,
10091 HInstruction* target, 10030 HInstruction* target,
10031 HInstruction* data_target,
10092 int object_offset, 10032 int object_offset,
10093 int elements_offset, 10033 int elements_offset,
10094 int elements_size) { 10034 int elements_size) {
10095 ASSERT(boilerplate_object->properties()->length() == 0); 10035 ASSERT(boilerplate_object->properties()->length() == 0);
10096 Zone* zone = this->zone(); 10036 Zone* zone = this->zone();
10097 HValue* result = NULL; 10037 HValue* result = NULL;
10098 10038
10099 HValue* object_header = 10039 HValue* object_header =
10100 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); 10040 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset));
10101 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10041 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10102 AddStoreMapConstant(object_header, boilerplate_object_map); 10042 AddStoreMapConstant(object_header, boilerplate_object_map);
10103 10043
10104 HInstruction* elements; 10044 HInstruction* elements;
10105 if (elements_size == 0) { 10045 if (elements_size == 0) {
10106 Handle<Object> elements_field = 10046 Handle<Object> elements_field =
10107 Handle<Object>(boilerplate_object->elements(), isolate()); 10047 Handle<Object>(boilerplate_object->elements(), isolate());
10108 elements = AddInstruction(new(zone) HConstant(elements_field)); 10048 elements = AddInstruction(new(zone) HConstant(elements_field));
10109 } else { 10049 } else {
10110 elements = AddInstruction(new(zone) HInnerAllocatedObject( 10050 if (data_target != NULL && boilerplate_object->HasFastDoubleElements()) {
10111 target, elements_offset)); 10051 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10052 data_target, elements_offset));
10053 } else {
10054 elements = AddInstruction(new(zone) HInnerAllocatedObject(
10055 target, elements_offset));
10056 }
10112 result = elements; 10057 result = elements;
10113 } 10058 }
10114 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements); 10059 AddStore(object_header, HObjectAccess::ForElementsPointer(), elements);
10115 10060
10116 Handle<Object> properties_field = 10061 Handle<Object> properties_field =
10117 Handle<Object>(boilerplate_object->properties(), isolate()); 10062 Handle<Object>(boilerplate_object->properties(), isolate());
10118 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10063 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array());
10119 HInstruction* properties = AddInstruction(new(zone) HConstant( 10064 HInstruction* properties = AddInstruction(new(zone) HConstant(
10120 properties_field)); 10065 properties_field));
10121 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 10066 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
(...skipping 16 matching lines...) Expand all
10138 10083
10139 return result; 10084 return result;
10140 } 10085 }
10141 10086
10142 10087
10143 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 10088 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
10144 Handle<JSObject> boilerplate_object, 10089 Handle<JSObject> boilerplate_object,
10145 Handle<JSObject> original_boilerplate_object, 10090 Handle<JSObject> original_boilerplate_object,
10146 HValue* object_properties, 10091 HValue* object_properties,
10147 HInstruction* target, 10092 HInstruction* target,
10148 int* offset) { 10093 int* offset,
10094 HInstruction* data_target,
10095 int* data_offset) {
10149 Zone* zone = this->zone(); 10096 Zone* zone = this->zone();
10150 Handle<DescriptorArray> descriptors( 10097 Handle<DescriptorArray> descriptors(
10151 boilerplate_object->map()->instance_descriptors()); 10098 boilerplate_object->map()->instance_descriptors());
10152 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); 10099 int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
10153 10100
10154 int copied_fields = 0; 10101 int copied_fields = 0;
10155 for (int i = 0; i < limit; i++) { 10102 for (int i = 0; i < limit; i++) {
10156 PropertyDetails details = descriptors->GetDetails(i); 10103 PropertyDetails details = descriptors->GetDetails(i);
10157 if (details.type() != FIELD) continue; 10104 if (details.type() != FIELD) continue;
10158 copied_fields++; 10105 copied_fields++;
(...skipping 13 matching lines...) Expand all
10172 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10119 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10173 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10120 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
10174 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), 10121 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index),
10175 isolate())); 10122 isolate()));
10176 HInstruction* value_instruction = 10123 HInstruction* value_instruction =
10177 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10124 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10178 10125
10179 AddStore(object_properties, access, value_instruction); 10126 AddStore(object_properties, access, value_instruction);
10180 10127
10181 BuildEmitDeepCopy(value_object, original_value_object, target, 10128 BuildEmitDeepCopy(value_object, original_value_object, target,
10182 offset, DONT_TRACK_ALLOCATION_SITE); 10129 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE);
10183 } else { 10130 } else {
10184 Representation representation = details.representation(); 10131 Representation representation = details.representation();
10185 HInstruction* value_instruction = 10132 HInstruction* value_instruction =
10186 AddInstruction(new(zone) HConstant(value)); 10133 AddInstruction(new(zone) HConstant(value));
10187 10134
10188 if (representation.IsDouble()) { 10135 if (representation.IsDouble()) {
10189 // Allocate a HeapNumber box and store the value into it. 10136 // Allocate a HeapNumber box and store the value into it.
10190 HInstruction* double_box = 10137 HInstruction* double_box;
10191 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10138 if (data_target != NULL) {
10139 double_box = AddInstruction(new(zone) HInnerAllocatedObject(
10140 data_target, *data_offset));
10141 *data_offset += HeapNumber::kSize;
10142 } else {
10143 double_box = AddInstruction(new(zone) HInnerAllocatedObject(
10144 target, *offset));
10145 *offset += HeapNumber::kSize;
10146 }
10192 AddStoreMapConstant(double_box, 10147 AddStoreMapConstant(double_box,
10193 isolate()->factory()->heap_number_map()); 10148 isolate()->factory()->heap_number_map());
10194 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 10149 AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
10195 value_instruction, Representation::Double()); 10150 value_instruction, Representation::Double());
10196 value_instruction = double_box; 10151 value_instruction = double_box;
10197 *offset += HeapNumber::kSize;
10198 } 10152 }
10199 10153
10200 AddStore(object_properties, access, value_instruction); 10154 AddStore(object_properties, access, value_instruction);
10201 } 10155 }
10202 } 10156 }
10203 10157
10204 int inobject_properties = boilerplate_object->map()->inobject_properties(); 10158 int inobject_properties = boilerplate_object->map()->inobject_properties();
10205 HInstruction* value_instruction = AddInstruction(new(zone) 10159 HInstruction* value_instruction = AddInstruction(new(zone)
10206 HConstant(isolate()->factory()->one_pointer_filler_map())); 10160 HConstant(isolate()->factory()->one_pointer_filler_map()));
10207 for (int i = copied_fields; i < inobject_properties; i++) { 10161 for (int i = copied_fields; i < inobject_properties; i++) {
10208 ASSERT(boilerplate_object->IsJSObject()); 10162 ASSERT(boilerplate_object->IsJSObject());
10209 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 10163 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
10210 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); 10164 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
10211 AddStore(object_properties, access, value_instruction); 10165 AddStore(object_properties, access, value_instruction);
10212 } 10166 }
10213 } 10167 }
10214 10168
10215 10169
10216 void HOptimizedGraphBuilder::BuildEmitElements( 10170 void HOptimizedGraphBuilder::BuildEmitElements(
10217 Handle<FixedArrayBase> elements, 10171 Handle<FixedArrayBase> elements,
10218 Handle<FixedArrayBase> original_elements, 10172 Handle<FixedArrayBase> original_elements,
10219 ElementsKind kind, 10173 ElementsKind kind,
10220 HValue* object_elements, 10174 HValue* object_elements,
10221 HInstruction* target, 10175 HInstruction* target,
10222 int* offset) { 10176 int* offset,
10177 HInstruction* data_target,
10178 int* data_offset) {
10223 Zone* zone = this->zone(); 10179 Zone* zone = this->zone();
10224 10180
10225 int elements_length = elements->length(); 10181 int elements_length = elements->length();
10226 HValue* object_elements_length = 10182 HValue* object_elements_length =
10227 AddInstruction(new(zone) HConstant(elements_length)); 10183 AddInstruction(new(zone) HConstant(elements_length));
10228 10184
10229 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); 10185 BuildInitializeElementsHeader(object_elements, kind, object_elements_length);
10230 10186
10231 // Copy elements backing store content. 10187 // Copy elements backing store content.
10232 if (elements->IsFixedDoubleArray()) { 10188 if (elements->IsFixedDoubleArray()) {
10233 BuildEmitFixedDoubleArray(elements, kind, object_elements); 10189 BuildEmitFixedDoubleArray(elements, kind, object_elements);
10234 } else if (elements->IsFixedArray()) { 10190 } else if (elements->IsFixedArray()) {
10235 BuildEmitFixedArray(elements, original_elements, kind, object_elements, 10191 BuildEmitFixedArray(elements, original_elements, kind, object_elements,
10236 target, offset); 10192 target, offset, data_target, data_offset);
10237 } else { 10193 } else {
10238 UNREACHABLE(); 10194 UNREACHABLE();
10239 } 10195 }
10240 } 10196 }
10241 10197
10242 10198
10243 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( 10199 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray(
10244 Handle<FixedArrayBase> elements, 10200 Handle<FixedArrayBase> elements,
10245 ElementsKind kind, 10201 ElementsKind kind,
10246 HValue* object_elements) { 10202 HValue* object_elements) {
(...skipping 12 matching lines...) Expand all
10259 } 10215 }
10260 } 10216 }
10261 10217
10262 10218
10263 void HOptimizedGraphBuilder::BuildEmitFixedArray( 10219 void HOptimizedGraphBuilder::BuildEmitFixedArray(
10264 Handle<FixedArrayBase> elements, 10220 Handle<FixedArrayBase> elements,
10265 Handle<FixedArrayBase> original_elements, 10221 Handle<FixedArrayBase> original_elements,
10266 ElementsKind kind, 10222 ElementsKind kind,
10267 HValue* object_elements, 10223 HValue* object_elements,
10268 HInstruction* target, 10224 HInstruction* target,
10269 int* offset) { 10225 int* offset,
10226 HInstruction* data_target,
10227 int* data_offset) {
10270 Zone* zone = this->zone(); 10228 Zone* zone = this->zone();
10271 HInstruction* boilerplate_elements = 10229 HInstruction* boilerplate_elements =
10272 AddInstruction(new(zone) HConstant(elements)); 10230 AddInstruction(new(zone) HConstant(elements));
10273 int elements_length = elements->length(); 10231 int elements_length = elements->length();
10274 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 10232 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
10275 Handle<FixedArray> original_fast_elements = 10233 Handle<FixedArray> original_fast_elements =
10276 Handle<FixedArray>::cast(original_elements); 10234 Handle<FixedArray>::cast(original_elements);
10277 for (int i = 0; i < elements_length; i++) { 10235 for (int i = 0; i < elements_length; i++) {
10278 Handle<Object> value(fast_elements->get(i), isolate()); 10236 Handle<Object> value(fast_elements->get(i), isolate());
10279 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); 10237 HValue* key_constant = AddInstruction(new(zone) HConstant(i));
10280 if (value->IsJSObject()) { 10238 if (value->IsJSObject()) {
10281 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 10239 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
10282 Handle<JSObject> original_value_object = Handle<JSObject>::cast( 10240 Handle<JSObject> original_value_object = Handle<JSObject>::cast(
10283 Handle<Object>(original_fast_elements->get(i), isolate())); 10241 Handle<Object>(original_fast_elements->get(i), isolate()));
10284 HInstruction* value_instruction = 10242 HInstruction* value_instruction =
10285 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); 10243 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset));
10286 AddInstruction(new(zone) HStoreKeyed( 10244 AddInstruction(new(zone) HStoreKeyed(
10287 object_elements, key_constant, value_instruction, kind)); 10245 object_elements, key_constant, value_instruction, kind));
10288 BuildEmitDeepCopy(value_object, original_value_object, target, 10246 BuildEmitDeepCopy(value_object, original_value_object, target,
10289 offset, DONT_TRACK_ALLOCATION_SITE); 10247 offset, data_target, data_offset, DONT_TRACK_ALLOCATION_SITE);
10290 } else { 10248 } else {
10291 HInstruction* value_instruction = 10249 HInstruction* value_instruction =
10292 AddInstruction(new(zone) HLoadKeyed( 10250 AddInstruction(new(zone) HLoadKeyed(
10293 boilerplate_elements, key_constant, NULL, kind, 10251 boilerplate_elements, key_constant, NULL, kind,
10294 ALLOW_RETURN_HOLE)); 10252 ALLOW_RETURN_HOLE));
10295 AddInstruction(new(zone) HStoreKeyed( 10253 AddInstruction(new(zone) HStoreKeyed(
10296 object_elements, key_constant, value_instruction, kind)); 10254 object_elements, key_constant, value_instruction, kind));
10297 } 10255 }
10298 } 10256 }
10299 } 10257 }
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
10601 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10559 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10602 HValue* value = Pop(); 10560 HValue* value = Pop();
10603 HValueOf* result = new(zone()) HValueOf(value); 10561 HValueOf* result = new(zone()) HValueOf(value);
10604 return ast_context()->ReturnInstruction(result, call->id()); 10562 return ast_context()->ReturnInstruction(result, call->id());
10605 } 10563 }
10606 10564
10607 10565
10608 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { 10566 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) {
10609 ASSERT(call->arguments()->length() == 2); 10567 ASSERT(call->arguments()->length() == 2);
10610 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); 10568 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral());
10611 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->handle())); 10569 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value()));
10612 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10570 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10613 HValue* date = Pop(); 10571 HValue* date = Pop();
10614 HDateField* result = new(zone()) HDateField(date, index); 10572 HDateField* result = new(zone()) HDateField(date, index);
10615 return ast_context()->ReturnInstruction(result, call->id()); 10573 return ast_context()->ReturnInstruction(result, call->id());
10616 } 10574 }
10617 10575
10618 10576
10619 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( 10577 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar(
10620 CallRuntime* call) { 10578 CallRuntime* call) {
10621 ASSERT(call->arguments()->length() == 3); 10579 ASSERT(call->arguments()->length() == 3);
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
11511 11469
11512 11470
11513 void HStatistics::Print() { 11471 void HStatistics::Print() {
11514 PrintF("Timing results:\n"); 11472 PrintF("Timing results:\n");
11515 int64_t sum = 0; 11473 int64_t sum = 0;
11516 for (int i = 0; i < timing_.length(); ++i) { 11474 for (int i = 0; i < timing_.length(); ++i) {
11517 sum += timing_[i]; 11475 sum += timing_[i];
11518 } 11476 }
11519 11477
11520 for (int i = 0; i < names_.length(); ++i) { 11478 for (int i = 0; i < names_.length(); ++i) {
11521 PrintF("%30s", names_[i]); 11479 PrintF("%32s", names_[i]);
11522 double ms = static_cast<double>(timing_[i]) / 1000; 11480 double ms = static_cast<double>(timing_[i]) / 1000;
11523 double percent = static_cast<double>(timing_[i]) * 100 / sum; 11481 double percent = static_cast<double>(timing_[i]) * 100 / sum;
11524 PrintF(" - %8.3f ms / %4.1f %% ", ms, percent); 11482 PrintF(" %8.3f ms / %4.1f %% ", ms, percent);
11525 11483
11526 unsigned size = sizes_[i]; 11484 unsigned size = sizes_[i];
11527 double size_percent = static_cast<double>(size) * 100 / total_size_; 11485 double size_percent = static_cast<double>(size) * 100 / total_size_;
11528 PrintF(" %9u bytes / %4.1f %%\n", size, size_percent); 11486 PrintF(" %9u bytes / %4.1f %%\n", size, size_percent);
11529 } 11487 }
11530 11488
11531 PrintF("----------------------------------------" 11489 PrintF("----------------------------------------"
11532 "---------------------------------------\n"); 11490 "---------------------------------------\n");
11533 int64_t total = create_graph_ + optimize_graph_ + generate_code_; 11491 int64_t total = create_graph_ + optimize_graph_ + generate_code_;
11534 PrintF("%30s - %8.3f ms / %4.1f %% \n", 11492 PrintF("%32s %8.3f ms / %4.1f %% \n",
11535 "Create graph", 11493 "Create graph",
11536 static_cast<double>(create_graph_) / 1000, 11494 static_cast<double>(create_graph_) / 1000,
11537 static_cast<double>(create_graph_) * 100 / total); 11495 static_cast<double>(create_graph_) * 100 / total);
11538 PrintF("%30s - %8.3f ms / %4.1f %% \n", 11496 PrintF("%32s %8.3f ms / %4.1f %% \n",
11539 "Optimize graph", 11497 "Optimize graph",
11540 static_cast<double>(optimize_graph_) / 1000, 11498 static_cast<double>(optimize_graph_) / 1000,
11541 static_cast<double>(optimize_graph_) * 100 / total); 11499 static_cast<double>(optimize_graph_) * 100 / total);
11542 PrintF("%30s - %8.3f ms / %4.1f %% \n", 11500 PrintF("%32s %8.3f ms / %4.1f %% \n",
11543 "Generate and install code", 11501 "Generate and install code",
11544 static_cast<double>(generate_code_) / 1000, 11502 static_cast<double>(generate_code_) / 1000,
11545 static_cast<double>(generate_code_) * 100 / total); 11503 static_cast<double>(generate_code_) * 100 / total);
11546 PrintF("----------------------------------------" 11504 PrintF("----------------------------------------"
11547 "---------------------------------------\n"); 11505 "---------------------------------------\n");
11548 PrintF("%30s - %8.3f ms (%.1f times slower than full code gen)\n", 11506 PrintF("%32s %8.3f ms (%.1f times slower than full code gen)\n",
11549 "Total", 11507 "Total",
11550 static_cast<double>(total) / 1000, 11508 static_cast<double>(total) / 1000,
11551 static_cast<double>(total) / full_code_gen_); 11509 static_cast<double>(total) / full_code_gen_);
11552 11510
11553 double source_size_in_kb = static_cast<double>(source_size_) / 1024; 11511 double source_size_in_kb = static_cast<double>(source_size_) / 1024;
11554 double normalized_time = source_size_in_kb > 0 11512 double normalized_time = source_size_in_kb > 0
11555 ? (static_cast<double>(total) / 1000) / source_size_in_kb 11513 ? (static_cast<double>(total) / 1000) / source_size_in_kb
11556 : 0; 11514 : 0;
11557 double normalized_size_in_kb = source_size_in_kb > 0 11515 double normalized_size_in_kb = source_size_in_kb > 0
11558 ? total_size_ / 1024 / source_size_in_kb 11516 ? total_size_ / 1024 / source_size_in_kb
11559 : 0; 11517 : 0;
11560 PrintF("%30s - %8.3f ms %7.3f kB allocated\n", 11518 PrintF("%32s %8.3f ms %7.3f kB allocated\n",
11561 "Average per kB source", 11519 "Average per kB source",
11562 normalized_time, normalized_size_in_kb); 11520 normalized_time, normalized_size_in_kb);
11563 } 11521 }
11564 11522
11565 11523
11566 void HStatistics::SaveTiming(const char* name, int64_t ticks, unsigned size) { 11524 void HStatistics::SaveTiming(const char* name, int64_t ticks, unsigned size) {
11567 if (name == HPhase::kFullCodeGen) { 11525 total_size_ += size;
11568 full_code_gen_ += ticks; 11526 for (int i = 0; i < names_.length(); ++i) {
11569 } else { 11527 if (strcmp(names_[i], name) == 0) {
11570 total_size_ += size; 11528 timing_[i] += ticks;
11571 for (int i = 0; i < names_.length(); ++i) { 11529 sizes_[i] += size;
11572 if (strcmp(names_[i], name) == 0) { 11530 return;
11573 timing_[i] += ticks;
11574 sizes_[i] += size;
11575 return;
11576 }
11577 } 11531 }
11578 names_.Add(name);
11579 timing_.Add(ticks);
11580 sizes_.Add(size);
11581 } 11532 }
11582 } 11533 names_.Add(name);
11583 11534 timing_.Add(ticks);
11584 11535 sizes_.Add(size);
11585 const char* const HPhase::kFullCodeGen = "Full code generator";
11586
11587
11588 HPhase::HPhase(const char* name, Isolate* isolate, Zone* zone) {
11589 Init(isolate, name, zone, NULL, NULL, NULL);
11590 }
11591
11592
11593 HPhase::HPhase(const char* name, HGraph* graph) {
11594 Init(graph->isolate(), name, graph->zone(), graph, NULL, NULL);
11595 }
11596
11597
11598 HPhase::HPhase(const char* name, LChunk* chunk) {
11599 Init(chunk->isolate(), name, chunk->zone(), NULL, chunk, NULL);
11600 }
11601
11602
11603 HPhase::HPhase(const char* name, LAllocator* allocator) {
11604 Init(allocator->isolate(), name, allocator->zone(), NULL, NULL, allocator);
11605 }
11606
11607
11608 void HPhase::Init(Isolate* isolate,
11609 const char* name,
11610 Zone* zone,
11611 HGraph* graph,
11612 LChunk* chunk,
11613 LAllocator* allocator) {
11614 isolate_ = isolate;
11615 name_ = name;
11616 zone_ = zone;
11617 graph_ = graph;
11618 chunk_ = chunk;
11619 allocator_ = allocator;
11620 if (allocator != NULL && chunk_ == NULL) {
11621 chunk_ = allocator->chunk();
11622 }
11623 if (FLAG_hydrogen_stats) {
11624 start_ticks_ = OS::Ticks();
11625 start_allocation_size_ = zone_->allocation_size();
11626 }
11627 } 11536 }
11628 11537
11629 11538
11630 HPhase::~HPhase() { 11539 HPhase::~HPhase() {
11631 if (FLAG_hydrogen_stats) { 11540 if (ShouldProduceTraceOutput()) {
11632 int64_t ticks = OS::Ticks() - start_ticks_; 11541 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11633 unsigned size = zone_->allocation_size() - start_allocation_size_;
11634 isolate_->GetHStatistics()->SaveTiming(name_, ticks, size);
11635 }
11636
11637 // Produce trace output if flag is set so that the first letter of the
11638 // phase name matches the command line parameter FLAG_trace_phase.
11639 if (FLAG_trace_hydrogen &&
11640 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL) {
11641 if (graph_ != NULL) {
11642 isolate_->GetHTracer()->TraceHydrogen(name_, graph_);
11643 }
11644 if (chunk_ != NULL) {
11645 isolate_->GetHTracer()->TraceLithium(name_, chunk_);
11646 }
11647 if (allocator_ != NULL) {
11648 isolate_->GetHTracer()->TraceLiveRanges(name_, allocator_);
11649 }
11650 } 11542 }
11651 11543
11652 #ifdef DEBUG 11544 #ifdef DEBUG
11653 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11545 graph_->Verify(false); // No full verify.
11654 if (allocator_ != NULL) allocator_->Verify();
11655 #endif 11546 #endif
11656 } 11547 }
11657 11548
11658 } } // namespace v8::internal 11549 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-environment-liveness.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698