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

Side by Side Diff: src/hydrogen.cc

Issue 7237024: Refactor handling of test expressions in the graph builder. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 5 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 879
880 class HRangeAnalysis BASE_EMBEDDED { 880 class HRangeAnalysis BASE_EMBEDDED {
881 public: 881 public:
882 explicit HRangeAnalysis(HGraph* graph) : graph_(graph), changed_ranges_(16) {} 882 explicit HRangeAnalysis(HGraph* graph) : graph_(graph), changed_ranges_(16) {}
883 883
884 void Analyze(); 884 void Analyze();
885 885
886 private: 886 private:
887 void TraceRange(const char* msg, ...); 887 void TraceRange(const char* msg, ...);
888 void Analyze(HBasicBlock* block); 888 void Analyze(HBasicBlock* block);
889 void InferControlFlowRange(HTest* test, HBasicBlock* dest); 889 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest);
890 void InferControlFlowRange(Token::Value op, HValue* value, HValue* other); 890 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other);
891 void InferPhiRange(HPhi* phi);
892 void InferRange(HValue* value); 891 void InferRange(HValue* value);
893 void RollBackTo(int index); 892 void RollBackTo(int index);
894 void AddRange(HValue* value, Range* range); 893 void AddRange(HValue* value, Range* range);
895 894
896 HGraph* graph_; 895 HGraph* graph_;
897 ZoneList<HValue*> changed_ranges_; 896 ZoneList<HValue*> changed_ranges_;
898 }; 897 };
899 898
900 899
901 void HRangeAnalysis::TraceRange(const char* msg, ...) { 900 void HRangeAnalysis::TraceRange(const char* msg, ...) {
(...skipping 13 matching lines...) Expand all
915 914
916 915
917 void HRangeAnalysis::Analyze(HBasicBlock* block) { 916 void HRangeAnalysis::Analyze(HBasicBlock* block) {
918 TraceRange("Analyzing block B%d\n", block->block_id()); 917 TraceRange("Analyzing block B%d\n", block->block_id());
919 918
920 int last_changed_range = changed_ranges_.length() - 1; 919 int last_changed_range = changed_ranges_.length() - 1;
921 920
922 // Infer range based on control flow. 921 // Infer range based on control flow.
923 if (block->predecessors()->length() == 1) { 922 if (block->predecessors()->length() == 1) {
924 HBasicBlock* pred = block->predecessors()->first(); 923 HBasicBlock* pred = block->predecessors()->first();
925 if (pred->end()->IsTest()) { 924 if (pred->end()->IsCompareIDAndBranch()) {
926 InferControlFlowRange(HTest::cast(pred->end()), block); 925 InferControlFlowRange(HCompareIDAndBranch::cast(pred->end()), block);
927 } 926 }
928 } 927 }
929 928
930 // Process phi instructions. 929 // Process phi instructions.
931 for (int i = 0; i < block->phis()->length(); ++i) { 930 for (int i = 0; i < block->phis()->length(); ++i) {
932 HPhi* phi = block->phis()->at(i); 931 HPhi* phi = block->phis()->at(i);
933 InferPhiRange(phi); 932 InferRange(phi);
934 } 933 }
935 934
936 // Go through all instructions of the current block. 935 // Go through all instructions of the current block.
937 HInstruction* instr = block->first(); 936 HInstruction* instr = block->first();
938 while (instr != block->end()) { 937 while (instr != block->end()) {
939 InferRange(instr); 938 InferRange(instr);
940 instr = instr->next(); 939 instr = instr->next();
941 } 940 }
942 941
943 // Continue analysis in all dominated blocks. 942 // Continue analysis in all dominated blocks.
944 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { 943 for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
945 Analyze(block->dominated_blocks()->at(i)); 944 Analyze(block->dominated_blocks()->at(i));
946 } 945 }
947 946
948 RollBackTo(last_changed_range); 947 RollBackTo(last_changed_range);
949 } 948 }
950 949
951 950
952 void HRangeAnalysis::InferControlFlowRange(HTest* test, HBasicBlock* dest) { 951 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test,
952 HBasicBlock* dest) {
953 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 953 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
954 if (test->value()->IsCompare()) { 954 if (test->GetInputRepresentation().IsInteger32()) {
955 HCompare* compare = HCompare::cast(test->value()); 955 Token::Value op = test->token();
956 if (compare->GetInputRepresentation().IsInteger32()) { 956 if (test->SecondSuccessor() == dest) {
957 Token::Value op = compare->token(); 957 op = Token::NegateCompareOp(op);
958 if (test->SecondSuccessor() == dest) {
959 op = Token::NegateCompareOp(op);
960 }
961 Token::Value inverted_op = Token::InvertCompareOp(op);
962 InferControlFlowRange(op, compare->left(), compare->right());
963 InferControlFlowRange(inverted_op, compare->right(), compare->left());
964 } 958 }
959 Token::Value inverted_op = Token::InvertCompareOp(op);
960 UpdateControlFlowRange(op, test->left(), test->right());
961 UpdateControlFlowRange(inverted_op, test->right(), test->left());
965 } 962 }
966 } 963 }
967 964
968 965
969 // We know that value [op] other. Use this information to update the range on 966 // We know that value [op] other. Use this information to update the range on
970 // value. 967 // value.
971 void HRangeAnalysis::InferControlFlowRange(Token::Value op, 968 void HRangeAnalysis::UpdateControlFlowRange(Token::Value op,
972 HValue* value, 969 HValue* value,
973 HValue* other) { 970 HValue* other) {
974 Range temp_range; 971 Range temp_range;
975 Range* range = other->range() != NULL ? other->range() : &temp_range; 972 Range* range = other->range() != NULL ? other->range() : &temp_range;
976 Range* new_range = NULL; 973 Range* new_range = NULL;
977 974
978 TraceRange("Control flow range infer %d %s %d\n", 975 TraceRange("Control flow range infer %d %s %d\n",
979 value->id(), 976 value->id(),
980 Token::Name(op), 977 Token::Name(op),
981 other->id()); 978 other->id());
982 979
983 if (op == Token::EQ || op == Token::EQ_STRICT) { 980 if (op == Token::EQ || op == Token::EQ_STRICT) {
(...skipping 10 matching lines...) Expand all
994 new_range->AddConstant(1); 991 new_range->AddConstant(1);
995 } 992 }
996 } 993 }
997 994
998 if (new_range != NULL && !new_range->IsMostGeneric()) { 995 if (new_range != NULL && !new_range->IsMostGeneric()) {
999 AddRange(value, new_range); 996 AddRange(value, new_range);
1000 } 997 }
1001 } 998 }
1002 999
1003 1000
1004 void HRangeAnalysis::InferPhiRange(HPhi* phi) {
1005 // TODO(twuerthinger): Infer loop phi ranges.
1006 InferRange(phi);
1007 }
1008
1009
1010 void HRangeAnalysis::InferRange(HValue* value) { 1001 void HRangeAnalysis::InferRange(HValue* value) {
1011 ASSERT(!value->HasRange()); 1002 ASSERT(!value->HasRange());
1012 if (!value->representation().IsNone()) { 1003 if (!value->representation().IsNone()) {
1013 value->ComputeInitialRange(); 1004 value->ComputeInitialRange();
1014 Range* range = value->range(); 1005 Range* range = value->range();
1015 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n", 1006 TraceRange("Initial inferred range of %d (%s) set to [%d,%d]\n",
1016 value->id(), 1007 value->id(),
1017 value->Mnemonic(), 1008 value->Mnemonic(),
1018 range->lower(), 1009 range->lower(),
1019 range->upper()); 1010 range->upper());
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); 1924 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input));
1934 } 1925 }
1935 } 1926 }
1936 } 1927 }
1937 1928
1938 1929
1939 void HGraph::MarkDeoptimizeOnUndefined() { 1930 void HGraph::MarkDeoptimizeOnUndefined() {
1940 HPhase phase("MarkDeoptimizeOnUndefined", this); 1931 HPhase phase("MarkDeoptimizeOnUndefined", this);
1941 // Compute DeoptimizeOnUndefined flag for phis. 1932 // Compute DeoptimizeOnUndefined flag for phis.
1942 // Any phi that can reach a use with DeoptimizeOnUndefined set must 1933 // Any phi that can reach a use with DeoptimizeOnUndefined set must
1943 // have DeoptimizeOnUndefined set. Currently only HCompare, with 1934 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with
1944 // double input representation, has this flag set. 1935 // double input representation, has this flag set.
1945 // The flag is used by HChange tagged->double, which must deoptimize 1936 // The flag is used by HChange tagged->double, which must deoptimize
1946 // if one of its uses has this flag set. 1937 // if one of its uses has this flag set.
1947 for (int i = 0; i < phi_list()->length(); i++) { 1938 for (int i = 0; i < phi_list()->length(); i++) {
1948 HPhi* phi = phi_list()->at(i); 1939 HPhi* phi = phi_list()->at(i);
1949 if (phi->representation().IsDouble()) { 1940 if (phi->representation().IsDouble()) {
1950 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { 1941 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
1951 if (it.value()->CheckFlag(HValue::kDeoptimizeOnUndefined)) { 1942 if (it.value()->CheckFlag(HValue::kDeoptimizeOnUndefined)) {
1952 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); 1943 RecursivelyMarkPhiDeoptimizeOnUndefined(phi);
1953 break; 1944 break;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 owner()->Push(value); 2062 owner()->Push(value);
2072 } 2063 }
2073 2064
2074 2065
2075 void TestContext::ReturnValue(HValue* value) { 2066 void TestContext::ReturnValue(HValue* value) {
2076 BuildBranch(value); 2067 BuildBranch(value);
2077 } 2068 }
2078 2069
2079 2070
2080 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { 2071 void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) {
2072 ASSERT(!instr->IsControlInstruction());
2081 owner()->AddInstruction(instr); 2073 owner()->AddInstruction(instr);
2082 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); 2074 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id);
2083 } 2075 }
2084 2076
2085 2077
2078 void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) {
2079 ASSERT(!instr->HasSideEffects());
2080 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2081 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2082 instr->SetSuccessorAt(0, empty_true);
2083 instr->SetSuccessorAt(1, empty_false);
2084 owner()->current_block()->Finish(instr);
2085 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id);
2086 owner()->set_current_block(join);
2087 }
2088
2089
2086 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { 2090 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) {
2091 ASSERT(!instr->IsControlInstruction());
2087 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2092 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2088 owner()->Bailout("bad value context for arguments object value"); 2093 return owner()->Bailout("bad value context for arguments object value");
2089 } 2094 }
2090 owner()->AddInstruction(instr); 2095 owner()->AddInstruction(instr);
2091 owner()->Push(instr); 2096 owner()->Push(instr);
2092 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); 2097 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id);
2093 } 2098 }
2094 2099
2095 2100
2101 void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) {
2102 ASSERT(!instr->HasSideEffects());
2103 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2104 return owner()->Bailout("bad value context for arguments object value");
2105 }
2106 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
2107 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
2108 instr->SetSuccessorAt(0, materialize_true);
2109 instr->SetSuccessorAt(1, materialize_false);
2110 owner()->current_block()->Finish(instr);
2111 owner()->set_current_block(materialize_true);
2112 owner()->Push(owner()->graph()->GetConstantTrue());
2113 owner()->set_current_block(materialize_false);
2114 owner()->Push(owner()->graph()->GetConstantFalse());
2115 HBasicBlock* join =
2116 owner()->CreateJoin(materialize_true, materialize_false, ast_id);
2117 owner()->set_current_block(join);
2118 ReturnValue(owner()->Pop());
Kevin Millikin (Chromium) 2011/06/30 13:31:05 No need for this last line. All it does is check
2119 }
2120
2121
2096 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { 2122 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) {
2123 ASSERT(!instr->IsControlInstruction());
2097 HGraphBuilder* builder = owner(); 2124 HGraphBuilder* builder = owner();
2098 builder->AddInstruction(instr); 2125 builder->AddInstruction(instr);
2099 // We expect a simulate after every expression with side effects, though 2126 // We expect a simulate after every expression with side effects, though
2100 // this one isn't actually needed (and wouldn't work if it were targeted). 2127 // this one isn't actually needed (and wouldn't work if it were targeted).
2101 if (instr->HasSideEffects()) { 2128 if (instr->HasSideEffects()) {
2102 builder->Push(instr); 2129 builder->Push(instr);
2103 builder->AddSimulate(ast_id); 2130 builder->AddSimulate(ast_id);
2104 builder->Pop(); 2131 builder->Pop();
2105 } 2132 }
2106 BuildBranch(instr); 2133 BuildBranch(instr);
2107 } 2134 }
2108 2135
2109 2136
2137 void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) {
2138 ASSERT(!instr->HasSideEffects());
2139 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
2140 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2141 instr->SetSuccessorAt(0, empty_true);
2142 instr->SetSuccessorAt(1, empty_false);
2143 owner()->current_block()->Finish(instr);
2144 empty_true->Goto(if_true());
2145 empty_false->Goto(if_false());
2146 owner()->set_current_block(NULL);
2147 }
2148
2149
2110 void TestContext::BuildBranch(HValue* value) { 2150 void TestContext::BuildBranch(HValue* value) {
2111 // We expect the graph to be in edge-split form: there is no edge that 2151 // We expect the graph to be in edge-split form: there is no edge that
2112 // connects a branch node to a join node. We conservatively ensure that 2152 // connects a branch node to a join node. We conservatively ensure that
2113 // property by always adding an empty block on the outgoing edges of this 2153 // property by always adding an empty block on the outgoing edges of this
2114 // branch. 2154 // branch.
2115 HGraphBuilder* builder = owner(); 2155 HGraphBuilder* builder = owner();
2116 if (value->CheckFlag(HValue::kIsArguments)) { 2156 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
2117 builder->Bailout("arguments object value in a test context"); 2157 builder->Bailout("arguments object value in a test context");
2118 } 2158 }
2119 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 2159 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
2120 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 2160 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
2121 HTest* test = new(zone()) HTest(value, empty_true, empty_false); 2161 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false);
2122 builder->current_block()->Finish(test); 2162 builder->current_block()->Finish(test);
2123 2163
2124 empty_true->Goto(if_true()); 2164 empty_true->Goto(if_true());
2125 empty_false->Goto(if_false()); 2165 empty_false->Goto(if_false());
2126 builder->set_current_block(NULL); 2166 builder->set_current_block(NULL);
2127 } 2167 }
2128 2168
2129 2169
2130 // HGraphBuilder infrastructure for bailing out and checking bailouts. 2170 // HGraphBuilder infrastructure for bailing out and checking bailouts.
2131 #define CHECK_BAILOUT(call) \ 2171 #define CHECK_BAILOUT(call) \
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 // Finish with deoptimize and add uses of enviroment values to 2657 // Finish with deoptimize and add uses of enviroment values to
2618 // account for invisible uses. 2658 // account for invisible uses.
2619 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); 2659 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
2620 set_current_block(NULL); 2660 set_current_block(NULL);
2621 break; 2661 break;
2622 } 2662 }
2623 2663
2624 // Otherwise generate a compare and branch. 2664 // Otherwise generate a compare and branch.
2625 CHECK_ALIVE(VisitForValue(clause->label())); 2665 CHECK_ALIVE(VisitForValue(clause->label()));
2626 HValue* label_value = Pop(); 2666 HValue* label_value = Pop();
2627 HCompare* compare = 2667 HCompareIDAndBranch* compare =
2628 new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT); 2668 new(zone()) HCompareIDAndBranch(tag_value,
2669 label_value,
2670 Token::EQ_STRICT);
2629 compare->SetInputRepresentation(Representation::Integer32()); 2671 compare->SetInputRepresentation(Representation::Integer32());
2630 ASSERT(!compare->HasSideEffects());
2631 AddInstruction(compare);
2632 HBasicBlock* body_block = graph()->CreateBasicBlock(); 2672 HBasicBlock* body_block = graph()->CreateBasicBlock();
2633 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 2673 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
2634 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block); 2674 compare->SetSuccessorAt(0, body_block);
2635 current_block()->Finish(branch); 2675 compare->SetSuccessorAt(1, next_test_block);
2676 current_block()->Finish(compare);
2636 set_current_block(next_test_block); 2677 set_current_block(next_test_block);
2637 } 2678 }
2638 2679
2639 // Save the current block to use for the default or to join with the 2680 // Save the current block to use for the default or to join with the
2640 // exit. This block is NULL if we deoptimized. 2681 // exit. This block is NULL if we deoptimized.
2641 HBasicBlock* last_block = current_block(); 2682 HBasicBlock* last_block = current_block();
2642 2683
2643 // 2. Loop over the clauses and the linked list of tests in lockstep, 2684 // 2. Loop over the clauses and the linked list of tests in lockstep,
2644 // translating the clause bodies. 2685 // translating the clause bodies.
2645 HBasicBlock* curr_test_block = first_test_block; 2686 HBasicBlock* curr_test_block = first_test_block;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2711 return statement->OsrEntryId() == info()->osr_ast_id(); 2752 return statement->OsrEntryId() == info()->osr_ast_id();
2712 } 2753 }
2713 2754
2714 2755
2715 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { 2756 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
2716 if (!HasOsrEntryAt(statement)) return; 2757 if (!HasOsrEntryAt(statement)) return;
2717 2758
2718 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); 2759 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
2719 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); 2760 HBasicBlock* osr_entry = graph()->CreateBasicBlock();
2720 HValue* true_value = graph()->GetConstantTrue(); 2761 HValue* true_value = graph()->GetConstantTrue();
2721 HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry); 2762 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry);
2722 current_block()->Finish(test); 2763 current_block()->Finish(test);
2723 2764
2724 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); 2765 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
2725 non_osr_entry->Goto(loop_predecessor); 2766 non_osr_entry->Goto(loop_predecessor);
2726 2767
2727 set_current_block(osr_entry); 2768 set_current_block(osr_entry);
2728 int osr_entry_id = statement->OsrEntryId(); 2769 int osr_entry_id = statement->OsrEntryId();
2729 // We want the correct environment at the OsrEntry instruction. Build 2770 // We want the correct environment at the OsrEntry instruction. Build
2730 // it explicitly. The expression stack should be empty. 2771 // it explicitly. The expression stack should be empty.
2731 ASSERT(environment()->ExpressionStackIsEmpty()); 2772 ASSERT(environment()->ExpressionStackIsEmpty());
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 Handle<SharedFunctionInfo> shared_info = 2996 Handle<SharedFunctionInfo> shared_info =
2956 SearchSharedFunctionInfo(info()->shared_info()->code(), 2997 SearchSharedFunctionInfo(info()->shared_info()->code(),
2957 expr); 2998 expr);
2958 if (shared_info.is_null()) { 2999 if (shared_info.is_null()) {
2959 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); 3000 shared_info = Compiler::BuildFunctionInfo(expr, info()->script());
2960 } 3001 }
2961 // We also have a stack overflow if the recursive compilation did. 3002 // We also have a stack overflow if the recursive compilation did.
2962 if (HasStackOverflow()) return; 3003 if (HasStackOverflow()) return;
2963 HFunctionLiteral* instr = 3004 HFunctionLiteral* instr =
2964 new(zone()) HFunctionLiteral(shared_info, expr->pretenure()); 3005 new(zone()) HFunctionLiteral(shared_info, expr->pretenure());
2965 ast_context()->ReturnInstruction(instr, expr->id()); 3006 return ast_context()->ReturnInstruction(instr, expr->id());
Kevin Millikin (Chromium) 2011/06/30 13:31:05 :)
2966 } 3007 }
2967 3008
2968 3009
2969 void HGraphBuilder::VisitSharedFunctionInfoLiteral( 3010 void HGraphBuilder::VisitSharedFunctionInfoLiteral(
2970 SharedFunctionInfoLiteral* expr) { 3011 SharedFunctionInfoLiteral* expr) {
2971 ASSERT(!HasStackOverflow()); 3012 ASSERT(!HasStackOverflow());
2972 ASSERT(current_block() != NULL); 3013 ASSERT(current_block() != NULL);
2973 ASSERT(current_block()->HasPredecessor()); 3014 ASSERT(current_block()->HasPredecessor());
2974 return Bailout("SharedFunctionInfoLiteral"); 3015 return Bailout("SharedFunctionInfoLiteral");
2975 } 3016 }
(...skipping 24 matching lines...) Expand all
3000 CHECK_BAILOUT(Visit(expr->else_expression())); 3041 CHECK_BAILOUT(Visit(expr->else_expression()));
3001 cond_false = current_block(); 3042 cond_false = current_block();
3002 } else { 3043 } else {
3003 cond_false = NULL; 3044 cond_false = NULL;
3004 } 3045 }
3005 3046
3006 if (!ast_context()->IsTest()) { 3047 if (!ast_context()->IsTest()) {
3007 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id()); 3048 HBasicBlock* join = CreateJoin(cond_true, cond_false, expr->id());
3008 set_current_block(join); 3049 set_current_block(join);
3009 if (join != NULL && !ast_context()->IsEffect()) { 3050 if (join != NULL && !ast_context()->IsEffect()) {
3010 ast_context()->ReturnValue(Pop()); 3051 return ast_context()->ReturnValue(Pop());
3011 } 3052 }
3012 } 3053 }
3013 } 3054 }
3014 3055
3015 3056
3016 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty( 3057 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty(
3017 Variable* var, LookupResult* lookup, bool is_store) { 3058 Variable* var, LookupResult* lookup, bool is_store) {
3018 if (var->is_this() || !info()->has_global_object()) { 3059 if (var->is_this() || !info()->has_global_object()) {
3019 return kUseGeneric; 3060 return kUseGeneric;
3020 } 3061 }
(...skipping 29 matching lines...) Expand all
3050 ASSERT(current_block()->HasPredecessor()); 3091 ASSERT(current_block()->HasPredecessor());
3051 Variable* variable = expr->AsVariable(); 3092 Variable* variable = expr->AsVariable();
3052 if (variable == NULL) { 3093 if (variable == NULL) {
3053 return Bailout("reference to rewritten variable"); 3094 return Bailout("reference to rewritten variable");
3054 } else if (variable->IsStackAllocated()) { 3095 } else if (variable->IsStackAllocated()) {
3055 HValue* value = environment()->Lookup(variable); 3096 HValue* value = environment()->Lookup(variable);
3056 if (variable->mode() == Variable::CONST && 3097 if (variable->mode() == Variable::CONST &&
3057 value == graph()->GetConstantHole()) { 3098 value == graph()->GetConstantHole()) {
3058 return Bailout("reference to uninitialized const variable"); 3099 return Bailout("reference to uninitialized const variable");
3059 } 3100 }
3060 ast_context()->ReturnValue(value); 3101 return ast_context()->ReturnValue(value);
3061 } else if (variable->IsContextSlot()) { 3102 } else if (variable->IsContextSlot()) {
3062 if (variable->mode() == Variable::CONST) { 3103 if (variable->mode() == Variable::CONST) {
3063 return Bailout("reference to const context slot"); 3104 return Bailout("reference to const context slot");
3064 } 3105 }
3065 HValue* context = BuildContextChainWalk(variable); 3106 HValue* context = BuildContextChainWalk(variable);
3066 int index = variable->AsSlot()->index(); 3107 int index = variable->AsSlot()->index();
3067 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index); 3108 HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index);
3068 ast_context()->ReturnInstruction(instr, expr->id()); 3109 return ast_context()->ReturnInstruction(instr, expr->id());
3069 } else if (variable->is_global()) { 3110 } else if (variable->is_global()) {
3070 LookupResult lookup; 3111 LookupResult lookup;
3071 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false); 3112 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
3072 3113
3073 if (type == kUseCell && 3114 if (type == kUseCell &&
3074 info()->global_object()->IsAccessCheckNeeded()) { 3115 info()->global_object()->IsAccessCheckNeeded()) {
3075 type = kUseGeneric; 3116 type = kUseGeneric;
3076 } 3117 }
3077 3118
3078 if (type == kUseCell) { 3119 if (type == kUseCell) {
3079 Handle<GlobalObject> global(info()->global_object()); 3120 Handle<GlobalObject> global(info()->global_object());
3080 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3121 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3081 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 3122 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
3082 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); 3123 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole);
3083 ast_context()->ReturnInstruction(instr, expr->id()); 3124 return ast_context()->ReturnInstruction(instr, expr->id());
3084 } else { 3125 } else {
3085 HValue* context = environment()->LookupContext(); 3126 HValue* context = environment()->LookupContext();
3086 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 3127 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
3087 AddInstruction(global_object); 3128 AddInstruction(global_object);
3088 HLoadGlobalGeneric* instr = 3129 HLoadGlobalGeneric* instr =
3089 new(zone()) HLoadGlobalGeneric(context, 3130 new(zone()) HLoadGlobalGeneric(context,
3090 global_object, 3131 global_object,
3091 variable->name(), 3132 variable->name(),
3092 ast_context()->is_for_typeof()); 3133 ast_context()->is_for_typeof());
3093 instr->set_position(expr->position()); 3134 instr->set_position(expr->position());
3094 ASSERT(instr->HasSideEffects()); 3135 ASSERT(instr->HasSideEffects());
3095 ast_context()->ReturnInstruction(instr, expr->id()); 3136 return ast_context()->ReturnInstruction(instr, expr->id());
3096 } 3137 }
3097 } else { 3138 } else {
3098 return Bailout("reference to a variable which requires dynamic lookup"); 3139 return Bailout("reference to a variable which requires dynamic lookup");
3099 } 3140 }
3100 } 3141 }
3101 3142
3102 3143
3103 void HGraphBuilder::VisitLiteral(Literal* expr) { 3144 void HGraphBuilder::VisitLiteral(Literal* expr) {
3104 ASSERT(!HasStackOverflow()); 3145 ASSERT(!HasStackOverflow());
3105 ASSERT(current_block() != NULL); 3146 ASSERT(current_block() != NULL);
3106 ASSERT(current_block()->HasPredecessor()); 3147 ASSERT(current_block()->HasPredecessor());
3107 HConstant* instr = 3148 HConstant* instr =
3108 new(zone()) HConstant(expr->handle(), Representation::Tagged()); 3149 new(zone()) HConstant(expr->handle(), Representation::Tagged());
3109 ast_context()->ReturnInstruction(instr, expr->id()); 3150 return ast_context()->ReturnInstruction(instr, expr->id());
3110 } 3151 }
3111 3152
3112 3153
3113 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 3154 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
3114 ASSERT(!HasStackOverflow()); 3155 ASSERT(!HasStackOverflow());
3115 ASSERT(current_block() != NULL); 3156 ASSERT(current_block() != NULL);
3116 ASSERT(current_block()->HasPredecessor()); 3157 ASSERT(current_block()->HasPredecessor());
3117 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(), 3158 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(),
3118 expr->flags(), 3159 expr->flags(),
3119 expr->literal_index()); 3160 expr->literal_index());
3120 ast_context()->ReturnInstruction(instr, expr->id()); 3161 return ast_context()->ReturnInstruction(instr, expr->id());
3121 } 3162 }
3122 3163
3123 3164
3124 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 3165 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
3125 ASSERT(!HasStackOverflow()); 3166 ASSERT(!HasStackOverflow());
3126 ASSERT(current_block() != NULL); 3167 ASSERT(current_block() != NULL);
3127 ASSERT(current_block()->HasPredecessor()); 3168 ASSERT(current_block()->HasPredecessor());
3128 HValue* context = environment()->LookupContext(); 3169 HValue* context = environment()->LookupContext();
3129 HObjectLiteral* literal = 3170 HObjectLiteral* literal =
3130 new(zone()) HObjectLiteral(context, 3171 new(zone()) HObjectLiteral(context,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3180 } 3221 }
3181 3222
3182 if (expr->has_function()) { 3223 if (expr->has_function()) {
3183 // Return the result of the transformation to fast properties 3224 // Return the result of the transformation to fast properties
3184 // instead of the original since this operation changes the map 3225 // instead of the original since this operation changes the map
3185 // of the object. This makes sure that the original object won't 3226 // of the object. This makes sure that the original object won't
3186 // be used by other optimized code before it is transformed 3227 // be used by other optimized code before it is transformed
3187 // (e.g. because of code motion). 3228 // (e.g. because of code motion).
3188 HToFastProperties* result = new(zone()) HToFastProperties(Pop()); 3229 HToFastProperties* result = new(zone()) HToFastProperties(Pop());
3189 AddInstruction(result); 3230 AddInstruction(result);
3190 ast_context()->ReturnValue(result); 3231 return ast_context()->ReturnValue(result);
3191 } else { 3232 } else {
3192 ast_context()->ReturnValue(Pop()); 3233 return ast_context()->ReturnValue(Pop());
3193 } 3234 }
3194 } 3235 }
3195 3236
3196 3237
3197 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 3238 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
3198 ASSERT(!HasStackOverflow()); 3239 ASSERT(!HasStackOverflow());
3199 ASSERT(current_block() != NULL); 3240 ASSERT(current_block() != NULL);
3200 ASSERT(current_block()->HasPredecessor()); 3241 ASSERT(current_block()->HasPredecessor());
3201 ZoneList<Expression*>* subexprs = expr->values(); 3242 ZoneList<Expression*>* subexprs = expr->values();
3202 int length = subexprs->length(); 3243 int length = subexprs->length();
(...skipping 23 matching lines...) Expand all
3226 elements = new(zone()) HLoadElements(literal); 3267 elements = new(zone()) HLoadElements(literal);
3227 AddInstruction(elements); 3268 AddInstruction(elements);
3228 } 3269 }
3229 3270
3230 HValue* key = AddInstruction( 3271 HValue* key = AddInstruction(
3231 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), 3272 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
3232 Representation::Integer32())); 3273 Representation::Integer32()));
3233 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); 3274 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
3234 AddSimulate(expr->GetIdForElement(i)); 3275 AddSimulate(expr->GetIdForElement(i));
3235 } 3276 }
3236 ast_context()->ReturnValue(Pop()); 3277 return ast_context()->ReturnValue(Pop());
3237 } 3278 }
3238 3279
3239 3280
3240 // Sets the lookup result and returns true if the store can be inlined. 3281 // Sets the lookup result and returns true if the store can be inlined.
3241 static bool ComputeStoredField(Handle<Map> type, 3282 static bool ComputeStoredField(Handle<Map> type,
3242 Handle<String> name, 3283 Handle<String> name,
3243 LookupResult* lookup) { 3284 LookupResult* lookup) {
3244 type->LookupInDescriptors(NULL, *name, lookup); 3285 type->LookupInDescriptors(NULL, *name, lookup);
3245 if (!lookup->IsPropertyOrTransition()) return false; 3286 if (!lookup->IsPropertyOrTransition()) return false;
3246 if (lookup->type() == FIELD) return true; 3287 if (lookup->type() == FIELD) return true;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3388 // unoptimized code). 3429 // unoptimized code).
3389 if (instr->HasSideEffects()) { 3430 if (instr->HasSideEffects()) {
3390 if (ast_context()->IsEffect()) { 3431 if (ast_context()->IsEffect()) {
3391 AddSimulate(expr->id()); 3432 AddSimulate(expr->id());
3392 } else { 3433 } else {
3393 Push(value); 3434 Push(value);
3394 AddSimulate(expr->id()); 3435 AddSimulate(expr->id());
3395 Drop(1); 3436 Drop(1);
3396 } 3437 }
3397 } 3438 }
3398 ast_context()->ReturnValue(value); 3439 return ast_context()->ReturnValue(value);
3399 return;
3400 } 3440 }
3401 } 3441 }
3402 3442
3403 ASSERT(join != NULL); 3443 ASSERT(join != NULL);
3404 join->SetJoinId(expr->id()); 3444 join->SetJoinId(expr->id());
3405 set_current_block(join); 3445 set_current_block(join);
3406 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 3446 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
3407 } 3447 }
3408 3448
3409 3449
3410 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 3450 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
3411 Property* prop = expr->target()->AsProperty(); 3451 Property* prop = expr->target()->AsProperty();
3412 ASSERT(prop != NULL); 3452 ASSERT(prop != NULL);
3413 expr->RecordTypeFeedback(oracle()); 3453 expr->RecordTypeFeedback(oracle());
3414 CHECK_ALIVE(VisitForValue(prop->obj())); 3454 CHECK_ALIVE(VisitForValue(prop->obj()));
3415 3455
3416 HValue* value = NULL; 3456 HValue* value = NULL;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3448 HValue* key = Pop(); 3488 HValue* key = Pop();
3449 HValue* object = Pop(); 3489 HValue* object = Pop();
3450 bool has_side_effects = false; 3490 bool has_side_effects = false;
3451 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 3491 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
3452 expr->position(), 3492 expr->position(),
3453 true, // is_store 3493 true, // is_store
3454 &has_side_effects); 3494 &has_side_effects);
3455 Push(value); 3495 Push(value);
3456 ASSERT(has_side_effects); // Stores always have side effects. 3496 ASSERT(has_side_effects); // Stores always have side effects.
3457 AddSimulate(expr->AssignmentId()); 3497 AddSimulate(expr->AssignmentId());
3458 ast_context()->ReturnValue(Pop()); 3498 return ast_context()->ReturnValue(Pop());
3459 return;
3460 } 3499 }
3461 Push(value); 3500 Push(value);
3462 instr->set_position(expr->position()); 3501 instr->set_position(expr->position());
3463 AddInstruction(instr); 3502 AddInstruction(instr);
3464 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3503 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3465 ast_context()->ReturnValue(Pop()); 3504 return ast_context()->ReturnValue(Pop());
3466 } 3505 }
3467 3506
3468 3507
3469 // Because not every expression has a position and there is not common 3508 // Because not every expression has a position and there is not common
3470 // superclass of Assignment and CountOperation, we cannot just pass the 3509 // superclass of Assignment and CountOperation, we cannot just pass the
3471 // owning expression instead of position and ast_id separately. 3510 // owning expression instead of position and ast_id separately.
3472 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 3511 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
3473 HValue* value, 3512 HValue* value,
3474 int position, 3513 int position,
3475 int ast_id) { 3514 int ast_id) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3543 3582
3544 HValue* context = BuildContextChainWalk(var); 3583 HValue* context = BuildContextChainWalk(var);
3545 int index = var->AsSlot()->index(); 3584 int index = var->AsSlot()->index();
3546 HStoreContextSlot* instr = 3585 HStoreContextSlot* instr =
3547 new(zone()) HStoreContextSlot(context, index, Top()); 3586 new(zone()) HStoreContextSlot(context, index, Top());
3548 AddInstruction(instr); 3587 AddInstruction(instr);
3549 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3588 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3550 } else { 3589 } else {
3551 return Bailout("compound assignment to lookup slot"); 3590 return Bailout("compound assignment to lookup slot");
3552 } 3591 }
3553 ast_context()->ReturnValue(Pop()); 3592 return ast_context()->ReturnValue(Pop());
3554 3593
3555 } else if (prop != NULL) { 3594 } else if (prop != NULL) {
3556 prop->RecordTypeFeedback(oracle()); 3595 prop->RecordTypeFeedback(oracle());
3557 3596
3558 if (prop->key()->IsPropertyName()) { 3597 if (prop->key()->IsPropertyName()) {
3559 // Named property. 3598 // Named property.
3560 CHECK_ALIVE(VisitForValue(prop->obj())); 3599 CHECK_ALIVE(VisitForValue(prop->obj()));
3561 HValue* obj = Top(); 3600 HValue* obj = Top();
3562 3601
3563 HInstruction* load = NULL; 3602 HInstruction* load = NULL;
(...skipping 14 matching lines...) Expand all
3578 HInstruction* instr = BuildBinaryOperation(operation, left, right); 3617 HInstruction* instr = BuildBinaryOperation(operation, left, right);
3579 PushAndAdd(instr); 3618 PushAndAdd(instr);
3580 if (instr->HasSideEffects()) AddSimulate(operation->id()); 3619 if (instr->HasSideEffects()) AddSimulate(operation->id());
3581 3620
3582 HInstruction* store = BuildStoreNamed(obj, instr, prop); 3621 HInstruction* store = BuildStoreNamed(obj, instr, prop);
3583 AddInstruction(store); 3622 AddInstruction(store);
3584 // Drop the simulated receiver and value. Return the value. 3623 // Drop the simulated receiver and value. Return the value.
3585 Drop(2); 3624 Drop(2);
3586 Push(instr); 3625 Push(instr);
3587 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3626 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
3588 ast_context()->ReturnValue(Pop()); 3627 return ast_context()->ReturnValue(Pop());
3589 3628
3590 } else { 3629 } else {
3591 // Keyed property. 3630 // Keyed property.
3592 CHECK_ALIVE(VisitForValue(prop->obj())); 3631 CHECK_ALIVE(VisitForValue(prop->obj()));
3593 CHECK_ALIVE(VisitForValue(prop->key())); 3632 CHECK_ALIVE(VisitForValue(prop->key()));
3594 HValue* obj = environment()->ExpressionStackAt(1); 3633 HValue* obj = environment()->ExpressionStackAt(1);
3595 HValue* key = environment()->ExpressionStackAt(0); 3634 HValue* key = environment()->ExpressionStackAt(0);
3596 3635
3597 bool has_side_effects = false; 3636 bool has_side_effects = false;
3598 HValue* load = HandleKeyedElementAccess( 3637 HValue* load = HandleKeyedElementAccess(
(...skipping 16 matching lines...) Expand all
3615 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), 3654 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
3616 RelocInfo::kNoPosition, 3655 RelocInfo::kNoPosition,
3617 true, // is_store 3656 true, // is_store
3618 &has_side_effects); 3657 &has_side_effects);
3619 3658
3620 // Drop the simulated receiver, key, and value. Return the value. 3659 // Drop the simulated receiver, key, and value. Return the value.
3621 Drop(3); 3660 Drop(3);
3622 Push(instr); 3661 Push(instr);
3623 ASSERT(has_side_effects); // Stores always have side effects. 3662 ASSERT(has_side_effects); // Stores always have side effects.
3624 AddSimulate(expr->AssignmentId()); 3663 AddSimulate(expr->AssignmentId());
3625 ast_context()->ReturnValue(Pop()); 3664 return ast_context()->ReturnValue(Pop());
3626 } 3665 }
3627 3666
3628 } else { 3667 } else {
3629 return Bailout("invalid lhs in compound assignment"); 3668 return Bailout("invalid lhs in compound assignment");
3630 } 3669 }
3631 } 3670 }
3632 3671
3633 3672
3634 void HGraphBuilder::VisitAssignment(Assignment* expr) { 3673 void HGraphBuilder::VisitAssignment(Assignment* expr) {
3635 ASSERT(!HasStackOverflow()); 3674 ASSERT(!HasStackOverflow());
(...skipping 26 matching lines...) Expand all
3662 if (proxy->IsArguments()) return Bailout("assignment to arguments"); 3701 if (proxy->IsArguments()) return Bailout("assignment to arguments");
3663 3702
3664 // Handle the assignment. 3703 // Handle the assignment.
3665 if (var->IsStackAllocated()) { 3704 if (var->IsStackAllocated()) {
3666 // We do not allow the arguments object to occur in a context where it 3705 // We do not allow the arguments object to occur in a context where it
3667 // may escape, but assignments to stack-allocated locals are 3706 // may escape, but assignments to stack-allocated locals are
3668 // permitted. 3707 // permitted.
3669 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 3708 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
3670 HValue* value = Pop(); 3709 HValue* value = Pop();
3671 Bind(var, value); 3710 Bind(var, value);
3672 ast_context()->ReturnValue(value); 3711 return ast_context()->ReturnValue(value);
3673 3712
3674 } else if (var->IsContextSlot()) { 3713 } else if (var->IsContextSlot()) {
3675 ASSERT(var->mode() != Variable::CONST); 3714 ASSERT(var->mode() != Variable::CONST);
3676 // Bail out if we try to mutate a parameter value in a function using 3715 // Bail out if we try to mutate a parameter value in a function using
3677 // the arguments object. We do not (yet) correctly handle the 3716 // the arguments object. We do not (yet) correctly handle the
3678 // arguments property of the function. 3717 // arguments property of the function.
3679 if (info()->scope()->arguments() != NULL) { 3718 if (info()->scope()->arguments() != NULL) {
3680 // Parameters will rewrite to context slots. We have no direct way 3719 // Parameters will rewrite to context slots. We have no direct way
3681 // to detect that the variable is a parameter. 3720 // to detect that the variable is a parameter.
3682 int count = info()->scope()->num_parameters(); 3721 int count = info()->scope()->num_parameters();
3683 for (int i = 0; i < count; ++i) { 3722 for (int i = 0; i < count; ++i) {
3684 if (var == info()->scope()->parameter(i)) { 3723 if (var == info()->scope()->parameter(i)) {
3685 Bailout("assignment to parameter, function uses arguments object"); 3724 Bailout("assignment to parameter, function uses arguments object");
3686 } 3725 }
3687 } 3726 }
3688 } 3727 }
3689 3728
3690 CHECK_ALIVE(VisitForValue(expr->value())); 3729 CHECK_ALIVE(VisitForValue(expr->value()));
3691 HValue* context = BuildContextChainWalk(var); 3730 HValue* context = BuildContextChainWalk(var);
3692 int index = var->AsSlot()->index(); 3731 int index = var->AsSlot()->index();
3693 HStoreContextSlot* instr = 3732 HStoreContextSlot* instr =
3694 new(zone()) HStoreContextSlot(context, index, Top()); 3733 new(zone()) HStoreContextSlot(context, index, Top());
3695 AddInstruction(instr); 3734 AddInstruction(instr);
3696 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3735 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3697 ast_context()->ReturnValue(Pop()); 3736 return ast_context()->ReturnValue(Pop());
3698 3737
3699 } else if (var->is_global()) { 3738 } else if (var->is_global()) {
3700 CHECK_ALIVE(VisitForValue(expr->value())); 3739 CHECK_ALIVE(VisitForValue(expr->value()));
3701 HandleGlobalVariableAssignment(var, 3740 HandleGlobalVariableAssignment(var,
3702 Top(), 3741 Top(),
3703 expr->position(), 3742 expr->position(),
3704 expr->AssignmentId()); 3743 expr->AssignmentId());
3705 ast_context()->ReturnValue(Pop()); 3744 return ast_context()->ReturnValue(Pop());
3706 3745
3707 } else { 3746 } else {
3708 return Bailout("assignment to LOOKUP or const CONTEXT variable"); 3747 return Bailout("assignment to LOOKUP or const CONTEXT variable");
3709 } 3748 }
3710 3749
3711 } else if (prop != NULL) { 3750 } else if (prop != NULL) {
3712 HandlePropertyAssignment(expr); 3751 HandlePropertyAssignment(expr);
3713 } else { 3752 } else {
3714 return Bailout("invalid left-hand side in assignment"); 3753 return Bailout("invalid left-hand side in assignment");
3715 } 3754 }
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3948 elements->ClearFlag(HValue::kUseGVN); 3987 elements->ClearFlag(HValue::kUseGVN);
3949 HInstruction* length = 3988 HInstruction* length =
3950 AddInstruction(new(zone()) HExternalArrayLength(elements)); 3989 AddInstruction(new(zone()) HExternalArrayLength(elements));
3951 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 3990 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3952 external_elements = new(zone()) HLoadExternalArrayPointer(elements); 3991 external_elements = new(zone()) HLoadExternalArrayPointer(elements);
3953 AddInstruction(external_elements); 3992 AddInstruction(external_elements);
3954 } 3993 }
3955 if (type_todo[elements_kind]) { 3994 if (type_todo[elements_kind]) {
3956 HBasicBlock* if_true = graph()->CreateBasicBlock(); 3995 HBasicBlock* if_true = graph()->CreateBasicBlock();
3957 HBasicBlock* if_false = graph()->CreateBasicBlock(); 3996 HBasicBlock* if_false = graph()->CreateBasicBlock();
3958 HCompareConstantEq* compare = new(zone()) HCompareConstantEq( 3997 HCompareConstantEqAndBranch* compare =
3959 elements_kind_instr, 3998 new(zone()) HCompareConstantEqAndBranch(elements_kind_instr,
3960 elements_kind, 3999 elements_kind,
3961 Token::EQ_STRICT); 4000 Token::EQ_STRICT);
3962 AddInstruction(compare); 4001 compare->SetSuccessorAt(0, if_true);
3963 HTest* branch = new(zone()) HTest(compare, if_true, if_false); 4002 compare->SetSuccessorAt(1, if_false);
3964 current_block()->Finish(branch); 4003 current_block()->Finish(compare);
3965 4004
3966 set_current_block(if_true); 4005 set_current_block(if_true);
3967 HInstruction* access; 4006 HInstruction* access;
3968 if (elements_kind == JSObject::FAST_ELEMENTS) { 4007 if (elements_kind == JSObject::FAST_ELEMENTS) {
3969 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 4008 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
3970 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 4009 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
3971 HInstruction* typecheck = 4010 HHasInstanceTypeAndBranch* typecheck =
3972 AddInstruction(new(zone()) HHasInstanceType(object, JS_ARRAY_TYPE)); 4011 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
3973 HTest* test = new(zone()) HTest(typecheck, if_jsarray, if_fastobject); 4012 typecheck->SetSuccessorAt(0, if_jsarray);
3974 current_block()->Finish(test); 4013 typecheck->SetSuccessorAt(1, if_fastobject);
4014 current_block()->Finish(typecheck);
3975 4015
3976 set_current_block(if_jsarray); 4016 set_current_block(if_jsarray);
3977 HInstruction* length = new(zone()) HJSArrayLength(object); 4017 HInstruction* length = new(zone()) HJSArrayLength(object);
3978 AddInstruction(length); 4018 AddInstruction(length);
3979 length->ClearFlag(HValue::kUseGVN); 4019 length->ClearFlag(HValue::kUseGVN);
3980 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 4020 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3981 elements = AddInstruction(new(zone()) HLoadElements(object)); 4021 elements = AddInstruction(new(zone()) HLoadElements(object));
3982 elements->ClearFlag(HValue::kUseGVN); 4022 elements->ClearFlag(HValue::kUseGVN);
3983 if (is_store) { 4023 if (is_store) {
3984 access = AddInstruction( 4024 access = AddInstruction(
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
4171 &has_side_effects); 4211 &has_side_effects);
4172 if (has_side_effects) { 4212 if (has_side_effects) {
4173 if (ast_context()->IsEffect()) { 4213 if (ast_context()->IsEffect()) {
4174 AddSimulate(expr->id()); 4214 AddSimulate(expr->id());
4175 } else { 4215 } else {
4176 Push(load); 4216 Push(load);
4177 AddSimulate(expr->id()); 4217 AddSimulate(expr->id());
4178 Drop(1); 4218 Drop(1);
4179 } 4219 }
4180 } 4220 }
4181 ast_context()->ReturnValue(load); 4221 return ast_context()->ReturnValue(load);
4182 return;
4183 } 4222 }
4184 instr->set_position(expr->position()); 4223 instr->set_position(expr->position());
4185 ast_context()->ReturnInstruction(instr, expr->id()); 4224 return ast_context()->ReturnInstruction(instr, expr->id());
4186 } 4225 }
4187 4226
4188 4227
4189 void HGraphBuilder::AddCheckConstantFunction(Call* expr, 4228 void HGraphBuilder::AddCheckConstantFunction(Call* expr,
4190 HValue* receiver, 4229 HValue* receiver,
4191 Handle<Map> receiver_map, 4230 Handle<Map> receiver_map,
4192 bool smi_and_map_check) { 4231 bool smi_and_map_check) {
4193 // Constant functions have the nice property that the map will change if they 4232 // Constant functions have the nice property that the map will change if they
4194 // are overwritten. Therefore it is enough to check the map of the holder and 4233 // are overwritten. Therefore it is enough to check the map of the holder and
4195 // its prototypes. 4234 // its prototypes.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4263 HValue* context = environment()->LookupContext(); 4302 HValue* context = environment()->LookupContext();
4264 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); 4303 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);
4265 call->set_position(expr->position()); 4304 call->set_position(expr->position());
4266 PreProcessCall(call); 4305 PreProcessCall(call);
4267 4306
4268 if (join != NULL) { 4307 if (join != NULL) {
4269 AddInstruction(call); 4308 AddInstruction(call);
4270 if (!ast_context()->IsEffect()) Push(call); 4309 if (!ast_context()->IsEffect()) Push(call);
4271 current_block()->Goto(join); 4310 current_block()->Goto(join);
4272 } else { 4311 } else {
4273 ast_context()->ReturnInstruction(call, expr->id()); 4312 return ast_context()->ReturnInstruction(call, expr->id());
4274 return;
4275 } 4313 }
4276 } 4314 }
4277 4315
4278 // We assume that control flow is always live after an expression. So 4316 // We assume that control flow is always live after an expression. So
4279 // even without predecessors to the join block, we set it as the exit 4317 // even without predecessors to the join block, we set it as the exit
4280 // block and continue by adding instructions there. 4318 // block and continue by adding instructions there.
4281 ASSERT(join != NULL); 4319 ASSERT(join != NULL);
4282 if (join->HasPredecessor()) { 4320 if (join->HasPredecessor()) {
4283 set_current_block(join); 4321 set_current_block(join);
4284 join->SetJoinId(expr->id()); 4322 join->SetJoinId(expr->id());
4285 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 4323 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
4286 } else { 4324 } else {
4287 set_current_block(NULL); 4325 set_current_block(NULL);
4288 } 4326 }
4289 } 4327 }
4290 4328
4291 4329
4292 void HGraphBuilder::TraceInline(Handle<JSFunction> target, 4330 void HGraphBuilder::TraceInline(Handle<JSFunction> target,
4293 Handle<JSFunction> caller, 4331 Handle<JSFunction> caller,
4294 const char* reason) { 4332 const char* reason) {
4295 if (FLAG_trace_inlining) { 4333 if (FLAG_trace_inlining) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
4489 current_block()->AddLeaveInlined(undefined, function_return()); 4527 current_block()->AddLeaveInlined(undefined, function_return());
4490 } 4528 }
4491 } else { 4529 } else {
4492 // The graph builder assumes control can reach both branches of a 4530 // The graph builder assumes control can reach both branches of a
4493 // test, so we materialize the undefined value and test it rather than 4531 // test, so we materialize the undefined value and test it rather than
4494 // simply jumping to the false target. 4532 // simply jumping to the false target.
4495 // 4533 //
4496 // TODO(3168478): refactor to avoid this. 4534 // TODO(3168478): refactor to avoid this.
4497 HBasicBlock* empty_true = graph()->CreateBasicBlock(); 4535 HBasicBlock* empty_true = graph()->CreateBasicBlock();
4498 HBasicBlock* empty_false = graph()->CreateBasicBlock(); 4536 HBasicBlock* empty_false = graph()->CreateBasicBlock();
4499 HTest* test = new(zone()) HTest(undefined, empty_true, empty_false); 4537 HBranch* test = new(zone()) HBranch(undefined, empty_true, empty_false);
4500 current_block()->Finish(test); 4538 current_block()->Finish(test);
4501 4539
4502 empty_true->Goto(inlined_test_context()->if_true()); 4540 empty_true->Goto(inlined_test_context()->if_true());
4503 empty_false->Goto(inlined_test_context()->if_false()); 4541 empty_false->Goto(inlined_test_context()->if_false());
4504 } 4542 }
4505 } 4543 }
4506 4544
4507 // Fix up the function exits. 4545 // Fix up the function exits.
4508 if (inlined_test_context() != NULL) { 4546 if (inlined_test_context() != NULL) {
4509 HBasicBlock* if_true = inlined_test_context()->if_true(); 4547 HBasicBlock* if_true = inlined_test_context()->if_true();
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
4702 HValue* receiver = Pop(); 4740 HValue* receiver = Pop();
4703 Push(key); 4741 Push(key);
4704 Push(receiver); 4742 Push(receiver);
4705 4743
4706 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 4744 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4707 4745
4708 HValue* context = environment()->LookupContext(); 4746 HValue* context = environment()->LookupContext();
4709 call = new(zone()) HCallKeyed(context, key, argument_count); 4747 call = new(zone()) HCallKeyed(context, key, argument_count);
4710 call->set_position(expr->position()); 4748 call->set_position(expr->position());
4711 Drop(argument_count + 1); // 1 is the key. 4749 Drop(argument_count + 1); // 1 is the key.
4712 ast_context()->ReturnInstruction(call, expr->id()); 4750 return ast_context()->ReturnInstruction(call, expr->id());
4713 return;
4714 } 4751 }
4715 4752
4716 // Named function call. 4753 // Named function call.
4717 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 4754 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
4718 4755
4719 if (TryCallApply(expr)) return; 4756 if (TryCallApply(expr)) return;
4720 4757
4721 CHECK_ALIVE(VisitForValue(prop->obj())); 4758 CHECK_ALIVE(VisitForValue(prop->obj()));
4722 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4759 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4723 4760
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
4827 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 4864 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4828 4865
4829 // The function to call is treated as an argument to the call function 4866 // The function to call is treated as an argument to the call function
4830 // stub. 4867 // stub.
4831 call = new(zone()) HCallFunction(context, argument_count + 1); 4868 call = new(zone()) HCallFunction(context, argument_count + 1);
4832 Drop(argument_count + 1); 4869 Drop(argument_count + 1);
4833 } 4870 }
4834 } 4871 }
4835 4872
4836 call->set_position(expr->position()); 4873 call->set_position(expr->position());
4837 ast_context()->ReturnInstruction(call, expr->id()); 4874 return ast_context()->ReturnInstruction(call, expr->id());
4838 } 4875 }
4839 4876
4840 4877
4841 void HGraphBuilder::VisitCallNew(CallNew* expr) { 4878 void HGraphBuilder::VisitCallNew(CallNew* expr) {
4842 ASSERT(!HasStackOverflow()); 4879 ASSERT(!HasStackOverflow());
4843 ASSERT(current_block() != NULL); 4880 ASSERT(current_block() != NULL);
4844 ASSERT(current_block()->HasPredecessor()); 4881 ASSERT(current_block()->HasPredecessor());
4845 // The constructor function is also used as the receiver argument to the 4882 // The constructor function is also used as the receiver argument to the
4846 // JS construct call builtin. 4883 // JS construct call builtin.
4847 HValue* constructor = NULL; 4884 HValue* constructor = NULL;
4848 CHECK_ALIVE(constructor = VisitArgument(expr->expression())); 4885 CHECK_ALIVE(constructor = VisitArgument(expr->expression()));
4849 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 4886 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4850 4887
4851 HValue* context = environment()->LookupContext(); 4888 HValue* context = environment()->LookupContext();
4852 4889
4853 // The constructor is both an operand to the instruction and an argument 4890 // The constructor is both an operand to the instruction and an argument
4854 // to the construct call. 4891 // to the construct call.
4855 int arg_count = expr->arguments()->length() + 1; // Plus constructor. 4892 int arg_count = expr->arguments()->length() + 1; // Plus constructor.
4856 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); 4893 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count);
4857 call->set_position(expr->position()); 4894 call->set_position(expr->position());
4858 Drop(arg_count); 4895 Drop(arg_count);
4859 ast_context()->ReturnInstruction(call, expr->id()); 4896 return ast_context()->ReturnInstruction(call, expr->id());
4860 } 4897 }
4861 4898
4862 4899
4863 // Support for generating inlined runtime functions. 4900 // Support for generating inlined runtime functions.
4864 4901
4865 // Lookup table for generators for runtime calls that are generated inline. 4902 // Lookup table for generators for runtime calls that are generated inline.
4866 // Elements of the table are member pointers to functions of HGraphBuilder. 4903 // Elements of the table are member pointers to functions of HGraphBuilder.
4867 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 4904 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
4868 &HGraphBuilder::Generate##Name, 4905 &HGraphBuilder::Generate##Name,
4869 4906
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4901 } else { 4938 } else {
4902 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 4939 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
4903 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 4940 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
4904 4941
4905 Handle<String> name = expr->name(); 4942 Handle<String> name = expr->name();
4906 int argument_count = expr->arguments()->length(); 4943 int argument_count = expr->arguments()->length();
4907 HCallRuntime* call = 4944 HCallRuntime* call =
4908 new(zone()) HCallRuntime(name, function, argument_count); 4945 new(zone()) HCallRuntime(name, function, argument_count);
4909 call->set_position(RelocInfo::kNoPosition); 4946 call->set_position(RelocInfo::kNoPosition);
4910 Drop(argument_count); 4947 Drop(argument_count);
4911 ast_context()->ReturnInstruction(call, expr->id()); 4948 return ast_context()->ReturnInstruction(call, expr->id());
4912 } 4949 }
4913 } 4950 }
4914 4951
4915 4952
4916 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 4953 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
4917 ASSERT(!HasStackOverflow()); 4954 ASSERT(!HasStackOverflow());
4918 ASSERT(current_block() != NULL); 4955 ASSERT(current_block() != NULL);
4919 ASSERT(current_block()->HasPredecessor()); 4956 ASSERT(current_block()->HasPredecessor());
4920 switch (expr->op()) { 4957 switch (expr->op()) {
4921 case Token::DELETE: return VisitDelete(expr); 4958 case Token::DELETE: return VisitDelete(expr);
4922 case Token::VOID: return VisitVoid(expr); 4959 case Token::VOID: return VisitVoid(expr);
4923 case Token::TYPEOF: return VisitTypeof(expr); 4960 case Token::TYPEOF: return VisitTypeof(expr);
4924 case Token::ADD: return VisitAdd(expr); 4961 case Token::ADD: return VisitAdd(expr);
4925 case Token::SUB: return VisitSub(expr); 4962 case Token::SUB: return VisitSub(expr);
4926 case Token::BIT_NOT: return VisitBitNot(expr); 4963 case Token::BIT_NOT: return VisitBitNot(expr);
4927 case Token::NOT: return VisitNot(expr); 4964 case Token::NOT: return VisitNot(expr);
4928 default: UNREACHABLE(); 4965 default: UNREACHABLE();
4929 } 4966 }
4930 } 4967 }
4931 4968
4932 void HGraphBuilder::VisitDelete(UnaryOperation* expr) { 4969 void HGraphBuilder::VisitDelete(UnaryOperation* expr) {
4933 Property* prop = expr->expression()->AsProperty(); 4970 Property* prop = expr->expression()->AsProperty();
4934 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4971 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4935 if (prop == NULL && var == NULL) { 4972 if (prop == NULL && var == NULL) {
4936 // Result of deleting non-property, non-variable reference is true. 4973 // Result of deleting non-property, non-variable reference is true.
4937 // Evaluate the subexpression for side effects. 4974 // Evaluate the subexpression for side effects.
4938 CHECK_ALIVE(VisitForEffect(expr->expression())); 4975 CHECK_ALIVE(VisitForEffect(expr->expression()));
4939 ast_context()->ReturnValue(graph()->GetConstantTrue()); 4976 return ast_context()->ReturnValue(graph()->GetConstantTrue());
4940 } else if (var != NULL && 4977 } else if (var != NULL &&
4941 !var->is_global() && 4978 !var->is_global() &&
4942 var->AsSlot() != NULL && 4979 var->AsSlot() != NULL &&
4943 var->AsSlot()->type() != Slot::LOOKUP) { 4980 var->AsSlot()->type() != Slot::LOOKUP) {
4944 // Result of deleting non-global, non-dynamic variables is false. 4981 // Result of deleting non-global, non-dynamic variables is false.
4945 // The subexpression does not have side effects. 4982 // The subexpression does not have side effects.
4946 ast_context()->ReturnValue(graph()->GetConstantFalse()); 4983 return ast_context()->ReturnValue(graph()->GetConstantFalse());
4947 } else if (prop != NULL) { 4984 } else if (prop != NULL) {
4948 if (prop->is_synthetic()) { 4985 if (prop->is_synthetic()) {
4949 // Result of deleting parameters is false, even when they rewrite 4986 // Result of deleting parameters is false, even when they rewrite
4950 // to accesses on the arguments object. 4987 // to accesses on the arguments object.
4951 ast_context()->ReturnValue(graph()->GetConstantFalse()); 4988 return ast_context()->ReturnValue(graph()->GetConstantFalse());
4952 } else { 4989 } else {
4953 CHECK_ALIVE(VisitForValue(prop->obj())); 4990 CHECK_ALIVE(VisitForValue(prop->obj()));
4954 CHECK_ALIVE(VisitForValue(prop->key())); 4991 CHECK_ALIVE(VisitForValue(prop->key()));
4955 HValue* key = Pop(); 4992 HValue* key = Pop();
4956 HValue* obj = Pop(); 4993 HValue* obj = Pop();
4957 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); 4994 HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key);
4958 ast_context()->ReturnInstruction(instr, expr->id()); 4995 return ast_context()->ReturnInstruction(instr, expr->id());
4959 } 4996 }
4960 } else if (var->is_global()) { 4997 } else if (var->is_global()) {
4961 Bailout("delete with global variable"); 4998 Bailout("delete with global variable");
4962 } else { 4999 } else {
4963 Bailout("delete with non-global variable"); 5000 Bailout("delete with non-global variable");
4964 } 5001 }
4965 } 5002 }
4966 5003
4967 5004
4968 void HGraphBuilder::VisitVoid(UnaryOperation* expr) { 5005 void HGraphBuilder::VisitVoid(UnaryOperation* expr) {
4969 CHECK_ALIVE(VisitForEffect(expr->expression())); 5006 CHECK_ALIVE(VisitForEffect(expr->expression()));
4970 ast_context()->ReturnValue(graph()->GetConstantUndefined()); 5007 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
4971 } 5008 }
4972 5009
4973 5010
4974 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { 5011 void HGraphBuilder::VisitTypeof(UnaryOperation* expr) {
4975 CHECK_ALIVE(VisitForTypeOf(expr->expression())); 5012 CHECK_ALIVE(VisitForTypeOf(expr->expression()));
4976 HValue* value = Pop(); 5013 HValue* value = Pop();
4977 ast_context()->ReturnInstruction(new(zone()) HTypeof(value), expr->id()); 5014 return ast_context()->ReturnInstruction(new(zone()) HTypeof(value),
5015 expr->id());
4978 } 5016 }
4979 5017
4980 5018
4981 void HGraphBuilder::VisitAdd(UnaryOperation* expr) { 5019 void HGraphBuilder::VisitAdd(UnaryOperation* expr) {
4982 CHECK_ALIVE(VisitForValue(expr->expression())); 5020 CHECK_ALIVE(VisitForValue(expr->expression()));
4983 HValue* value = Pop(); 5021 HValue* value = Pop();
4984 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1()); 5022 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1());
4985 ast_context()->ReturnInstruction(instr, expr->id()); 5023 return ast_context()->ReturnInstruction(instr, expr->id());
4986 } 5024 }
4987 5025
4988 5026
4989 void HGraphBuilder::VisitSub(UnaryOperation* expr) { 5027 void HGraphBuilder::VisitSub(UnaryOperation* expr) {
4990 CHECK_ALIVE(VisitForValue(expr->expression())); 5028 CHECK_ALIVE(VisitForValue(expr->expression()));
4991 HValue* value = Pop(); 5029 HValue* value = Pop();
4992 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); 5030 HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1());
4993 TypeInfo info = oracle()->UnaryType(expr); 5031 TypeInfo info = oracle()->UnaryType(expr);
4994 if (info.IsUninitialized()) { 5032 if (info.IsUninitialized()) {
4995 AddInstruction(new(zone()) HSoftDeoptimize); 5033 AddInstruction(new(zone()) HSoftDeoptimize);
4996 current_block()->MarkAsDeoptimizing(); 5034 current_block()->MarkAsDeoptimizing();
4997 info = TypeInfo::Unknown(); 5035 info = TypeInfo::Unknown();
4998 } 5036 }
4999 Representation rep = ToRepresentation(info); 5037 Representation rep = ToRepresentation(info);
5000 TraceRepresentation(expr->op(), info, instr, rep); 5038 TraceRepresentation(expr->op(), info, instr, rep);
5001 instr->AssumeRepresentation(rep); 5039 instr->AssumeRepresentation(rep);
5002 ast_context()->ReturnInstruction(instr, expr->id()); 5040 return ast_context()->ReturnInstruction(instr, expr->id());
5003 } 5041 }
5004 5042
5005 5043
5006 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { 5044 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
5007 CHECK_ALIVE(VisitForValue(expr->expression())); 5045 CHECK_ALIVE(VisitForValue(expr->expression()));
5008 HValue* value = Pop(); 5046 HValue* value = Pop();
5009 TypeInfo info = oracle()->UnaryType(expr); 5047 TypeInfo info = oracle()->UnaryType(expr);
5010 if (info.IsUninitialized()) { 5048 if (info.IsUninitialized()) {
5011 AddInstruction(new(zone()) HSoftDeoptimize); 5049 AddInstruction(new(zone()) HSoftDeoptimize);
5012 current_block()->MarkAsDeoptimizing(); 5050 current_block()->MarkAsDeoptimizing();
5013 } 5051 }
5014 HInstruction* instr = new(zone()) HBitNot(value); 5052 HInstruction* instr = new(zone()) HBitNot(value);
5015 ast_context()->ReturnInstruction(instr, expr->id()); 5053 return ast_context()->ReturnInstruction(instr, expr->id());
5016 } 5054 }
5017 5055
5018 5056
5019 void HGraphBuilder::VisitNot(UnaryOperation* expr) { 5057 void HGraphBuilder::VisitNot(UnaryOperation* expr) {
5020 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here. 5058 // TODO(svenpanne) Perhaps a switch/virtual function is nicer here.
5021 if (ast_context()->IsTest()) { 5059 if (ast_context()->IsTest()) {
5022 TestContext* context = TestContext::cast(ast_context()); 5060 TestContext* context = TestContext::cast(ast_context());
5023 VisitForControl(expr->expression(), 5061 VisitForControl(expr->expression(),
5024 context->if_false(), 5062 context->if_false(),
5025 context->if_true()); 5063 context->if_true());
(...skipping 24 matching lines...) Expand all
5050 materialize_true->SetJoinId(expr->expression()->id()); 5088 materialize_true->SetJoinId(expr->expression()->id());
5051 set_current_block(materialize_true); 5089 set_current_block(materialize_true);
5052 Push(graph()->GetConstantTrue()); 5090 Push(graph()->GetConstantTrue());
5053 } else { 5091 } else {
5054 materialize_true = NULL; 5092 materialize_true = NULL;
5055 } 5093 }
5056 5094
5057 HBasicBlock* join = 5095 HBasicBlock* join =
5058 CreateJoin(materialize_false, materialize_true, expr->id()); 5096 CreateJoin(materialize_false, materialize_true, expr->id());
5059 set_current_block(join); 5097 set_current_block(join);
5060 if (join != NULL) ast_context()->ReturnValue(Pop()); 5098 if (join != NULL) return ast_context()->ReturnValue(Pop());
5061 } 5099 }
5062 5100
5063 5101
5064 HInstruction* HGraphBuilder::BuildIncrement(bool returns_original_input, 5102 HInstruction* HGraphBuilder::BuildIncrement(bool returns_original_input,
5065 CountOperation* expr) { 5103 CountOperation* expr) {
5066 // The input to the count operation is on top of the expression stack. 5104 // The input to the count operation is on top of the expression stack.
5067 TypeInfo info = oracle()->IncrementType(expr); 5105 TypeInfo info = oracle()->IncrementType(expr);
5068 Representation rep = ToRepresentation(info); 5106 Representation rep = ToRepresentation(info);
5069 if (rep.IsTagged()) { 5107 if (rep.IsTagged()) {
5070 rep = Representation::Integer32(); 5108 rep = Representation::Integer32();
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
5225 // original value if necessary. 5263 // original value if necessary.
5226 Drop(1); 5264 Drop(1);
5227 environment()->SetExpressionStackAt(0, after); 5265 environment()->SetExpressionStackAt(0, after);
5228 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 5266 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
5229 ASSERT(has_side_effects); // Stores always have side effects. 5267 ASSERT(has_side_effects); // Stores always have side effects.
5230 AddSimulate(expr->AssignmentId()); 5268 AddSimulate(expr->AssignmentId());
5231 } 5269 }
5232 } 5270 }
5233 5271
5234 Drop(returns_original_input ? 2 : 1); 5272 Drop(returns_original_input ? 2 : 1);
5235 ast_context()->ReturnValue(expr->is_postfix() ? input : after); 5273 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
5236 } 5274 }
5237 5275
5238 5276
5239 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, 5277 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string,
5240 HValue* index) { 5278 HValue* index) {
5241 AddInstruction(new(zone()) HCheckNonSmi(string)); 5279 AddInstruction(new(zone()) HCheckNonSmi(string));
5242 AddInstruction(HCheckInstanceType::NewIsString(string)); 5280 AddInstruction(HCheckInstanceType::NewIsString(string));
5243 HStringLength* length = new(zone()) HStringLength(string); 5281 HStringLength* length = new(zone()) HStringLength(string);
5244 AddInstruction(length); 5282 AddInstruction(length);
5245 HInstruction* checked_index = 5283 HInstruction* checked_index =
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
5385 Visit(expr->right()); 5423 Visit(expr->right());
5386 } 5424 }
5387 5425
5388 } else if (ast_context()->IsValue()) { 5426 } else if (ast_context()->IsValue()) {
5389 CHECK_ALIVE(VisitForValue(expr->left())); 5427 CHECK_ALIVE(VisitForValue(expr->left()));
5390 ASSERT(current_block() != NULL); 5428 ASSERT(current_block() != NULL);
5391 5429
5392 // We need an extra block to maintain edge-split form. 5430 // We need an extra block to maintain edge-split form.
5393 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 5431 HBasicBlock* empty_block = graph()->CreateBasicBlock();
5394 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 5432 HBasicBlock* eval_right = graph()->CreateBasicBlock();
5395 HTest* test = is_logical_and 5433 HBranch* test = is_logical_and
5396 ? new(zone()) HTest(Top(), eval_right, empty_block) 5434 ? new(zone()) HBranch(Top(), eval_right, empty_block)
5397 : new(zone()) HTest(Top(), empty_block, eval_right); 5435 : new(zone()) HBranch(Top(), empty_block, eval_right);
5398 current_block()->Finish(test); 5436 current_block()->Finish(test);
5399 5437
5400 set_current_block(eval_right); 5438 set_current_block(eval_right);
5401 Drop(1); // Value of the left subexpression. 5439 Drop(1); // Value of the left subexpression.
5402 CHECK_BAILOUT(VisitForValue(expr->right())); 5440 CHECK_BAILOUT(VisitForValue(expr->right()));
5403 5441
5404 HBasicBlock* join_block = 5442 HBasicBlock* join_block =
5405 CreateJoin(empty_block, current_block(), expr->id()); 5443 CreateJoin(empty_block, current_block(), expr->id());
5406 set_current_block(join_block); 5444 set_current_block(join_block);
5407 ast_context()->ReturnValue(Pop()); 5445 return ast_context()->ReturnValue(Pop());
5408 5446
5409 } else { 5447 } else {
5410 ASSERT(ast_context()->IsEffect()); 5448 ASSERT(ast_context()->IsEffect());
5411 // In an effect context, we don't need the value of the left subexpression, 5449 // In an effect context, we don't need the value of the left subexpression,
5412 // only its control flow and side effects. We need an extra block to 5450 // only its control flow and side effects. We need an extra block to
5413 // maintain edge-split form. 5451 // maintain edge-split form.
5414 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 5452 HBasicBlock* empty_block = graph()->CreateBasicBlock();
5415 HBasicBlock* right_block = graph()->CreateBasicBlock(); 5453 HBasicBlock* right_block = graph()->CreateBasicBlock();
5416 if (is_logical_and) { 5454 if (is_logical_and) {
5417 CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block)); 5455 CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5449 } 5487 }
5450 5488
5451 5489
5452 void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { 5490 void HGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
5453 CHECK_ALIVE(VisitForValue(expr->left())); 5491 CHECK_ALIVE(VisitForValue(expr->left()));
5454 CHECK_ALIVE(VisitForValue(expr->right())); 5492 CHECK_ALIVE(VisitForValue(expr->right()));
5455 HValue* right = Pop(); 5493 HValue* right = Pop();
5456 HValue* left = Pop(); 5494 HValue* left = Pop();
5457 HInstruction* instr = BuildBinaryOperation(expr, left, right); 5495 HInstruction* instr = BuildBinaryOperation(expr, left, right);
5458 instr->set_position(expr->position()); 5496 instr->set_position(expr->position());
5459 ast_context()->ReturnInstruction(instr, expr->id()); 5497 return ast_context()->ReturnInstruction(instr, expr->id());
5460 } 5498 }
5461 5499
5462 5500
5463 void HGraphBuilder::TraceRepresentation(Token::Value op, 5501 void HGraphBuilder::TraceRepresentation(Token::Value op,
5464 TypeInfo info, 5502 TypeInfo info,
5465 HValue* value, 5503 HValue* value,
5466 Representation rep) { 5504 Representation rep) {
5467 if (!FLAG_trace_representation) return; 5505 if (!FLAG_trace_representation) return;
5468 // TODO(svenpanne) Under which circumstances are we actually not flexible? 5506 // TODO(svenpanne) Under which circumstances are we actually not flexible?
5469 // At first glance, this looks a bit weird... 5507 // At first glance, this looks a bit weird...
(...skipping 17 matching lines...) Expand all
5487 if (info.IsNumber()) return Representation::Double(); 5525 if (info.IsNumber()) return Representation::Double();
5488 return Representation::Tagged(); 5526 return Representation::Tagged();
5489 } 5527 }
5490 5528
5491 5529
5492 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* compare_expr, 5530 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* compare_expr,
5493 Expression* expr, 5531 Expression* expr,
5494 Handle<String> check) { 5532 Handle<String> check) {
5495 CHECK_ALIVE(VisitForTypeOf(expr)); 5533 CHECK_ALIVE(VisitForTypeOf(expr));
5496 HValue* expr_value = Pop(); 5534 HValue* expr_value = Pop();
5497 HInstruction* instr = new(zone()) HTypeofIs(expr_value, check); 5535 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(expr_value, check);
5498 instr->set_position(compare_expr->position()); 5536 instr->set_position(compare_expr->position());
5499 ast_context()->ReturnInstruction(instr, compare_expr->id()); 5537 return ast_context()->ReturnControl(instr, compare_expr->id());
5500 } 5538 }
5501 5539
5502 5540
5503 void HGraphBuilder::HandleLiteralCompareUndefined( 5541 void HGraphBuilder::HandleLiteralCompareUndefined(
5504 CompareOperation* compare_expr, Expression* expr) { 5542 CompareOperation* compare_expr, Expression* expr) {
5505 CHECK_ALIVE(VisitForValue(expr)); 5543 CHECK_ALIVE(VisitForValue(expr));
5506 HValue* lhs = Pop(); 5544 HValue* lhs = Pop();
5507 HValue* rhs = graph()->GetConstantUndefined(); 5545 HValue* rhs = graph()->GetConstantUndefined();
5508 HInstruction* instr = 5546 HCompareObjectEqAndBranch* instr =
5509 new(zone()) HCompareObjectEq(lhs, rhs); 5547 new(zone()) HCompareObjectEqAndBranch(lhs, rhs);
5510 instr->set_position(compare_expr->position()); 5548 instr->set_position(compare_expr->position());
5511 ast_context()->ReturnInstruction(instr, compare_expr->id()); 5549 return ast_context()->ReturnControl(instr, compare_expr->id());
5512 } 5550 }
5513 5551
5514 5552
5515 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 5553 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
5516 ASSERT(!HasStackOverflow()); 5554 ASSERT(!HasStackOverflow());
5517 ASSERT(current_block() != NULL); 5555 ASSERT(current_block() != NULL);
5518 ASSERT(current_block()->HasPredecessor()); 5556 ASSERT(current_block()->HasPredecessor());
5519 if (IsClassOfTest(expr)) { 5557 if (IsClassOfTest(expr)) {
5520 CallRuntime* call = expr->left()->AsCallRuntime(); 5558 CallRuntime* call = expr->left()->AsCallRuntime();
5559 ASSERT(call->arguments()->length() == 1);
5521 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5560 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5522 HValue* value = Pop(); 5561 HValue* value = Pop();
5523 Literal* literal = expr->right()->AsLiteral(); 5562 Literal* literal = expr->right()->AsLiteral();
5524 Handle<String> rhs = Handle<String>::cast(literal->handle()); 5563 Handle<String> rhs = Handle<String>::cast(literal->handle());
5525 HInstruction* instr = new(zone()) HClassOfTest(value, rhs); 5564 HClassOfTestAndBranch* instr =
5565 new(zone()) HClassOfTestAndBranch(value, rhs);
5526 instr->set_position(expr->position()); 5566 instr->set_position(expr->position());
5527 ast_context()->ReturnInstruction(instr, expr->id()); 5567 return ast_context()->ReturnControl(instr, expr->id());
5528 return;
5529 } 5568 }
5530 5569
5531 // Check for special cases that compare against literals. 5570 // Check for special cases that compare against literals.
5532 Expression *sub_expr; 5571 Expression *sub_expr;
5533 Handle<String> check; 5572 Handle<String> check;
5534 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 5573 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
5535 HandleLiteralCompareTypeof(expr, sub_expr, check); 5574 HandleLiteralCompareTypeof(expr, sub_expr, check);
5536 return; 5575 return;
5537 } 5576 }
5538 5577
(...skipping 10 matching lines...) Expand all
5549 type_info = TypeInfo::Unknown(); 5588 type_info = TypeInfo::Unknown();
5550 } 5589 }
5551 5590
5552 CHECK_ALIVE(VisitForValue(expr->left())); 5591 CHECK_ALIVE(VisitForValue(expr->left()));
5553 CHECK_ALIVE(VisitForValue(expr->right())); 5592 CHECK_ALIVE(VisitForValue(expr->right()));
5554 5593
5555 HValue* right = Pop(); 5594 HValue* right = Pop();
5556 HValue* left = Pop(); 5595 HValue* left = Pop();
5557 Token::Value op = expr->op(); 5596 Token::Value op = expr->op();
5558 5597
5559 HInstruction* instr = NULL;
5560 if (op == Token::INSTANCEOF) { 5598 if (op == Token::INSTANCEOF) {
5561 // Check to see if the rhs of the instanceof is a global function not 5599 // Check to see if the rhs of the instanceof is a global function not
5562 // residing in new space. If it is we assume that the function will stay the 5600 // residing in new space. If it is we assume that the function will stay the
5563 // same. 5601 // same.
5564 Handle<JSFunction> target = Handle<JSFunction>::null(); 5602 Handle<JSFunction> target = Handle<JSFunction>::null();
5565 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); 5603 Variable* var = expr->right()->AsVariableProxy()->AsVariable();
5566 bool global_function = (var != NULL) && var->is_global() && !var->is_this(); 5604 bool global_function = (var != NULL) && var->is_global() && !var->is_this();
5567 if (global_function && 5605 if (global_function &&
5568 info()->has_global_object() && 5606 info()->has_global_object() &&
5569 !info()->global_object()->IsAccessCheckNeeded()) { 5607 !info()->global_object()->IsAccessCheckNeeded()) {
(...skipping 10 matching lines...) Expand all
5580 if (!isolate()->heap()->InNewSpace(*candidate)) { 5618 if (!isolate()->heap()->InNewSpace(*candidate)) {
5581 target = candidate; 5619 target = candidate;
5582 } 5620 }
5583 } 5621 }
5584 } 5622 }
5585 5623
5586 // If the target is not null we have found a known global function that is 5624 // If the target is not null we have found a known global function that is
5587 // assumed to stay the same for this instanceof. 5625 // assumed to stay the same for this instanceof.
5588 if (target.is_null()) { 5626 if (target.is_null()) {
5589 HValue* context = environment()->LookupContext(); 5627 HValue* context = environment()->LookupContext();
5590 instr = new(zone()) HInstanceOf(context, left, right); 5628 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right);
5629 result->set_position(expr->position());
5630 return ast_context()->ReturnInstruction(result, expr->id());
5591 } else { 5631 } else {
5592 AddInstruction(new(zone()) HCheckFunction(right, target)); 5632 AddInstruction(new(zone()) HCheckFunction(right, target));
5593 instr = new(zone()) HInstanceOfKnownGlobal(left, target); 5633 HInstanceOfKnownGlobal* result =
5634 new(zone()) HInstanceOfKnownGlobal(left, target);
5635 result->set_position(expr->position());
5636 return ast_context()->ReturnInstruction(result, expr->id());
5594 } 5637 }
5595 } else if (op == Token::IN) { 5638 } else if (op == Token::IN) {
5596 instr = new(zone()) HIn(left, right); 5639 HIn* result = new(zone()) HIn(left, right);
5640 result->set_position(expr->position());
5641 return ast_context()->ReturnInstruction(result, expr->id());
5597 } else if (type_info.IsNonPrimitive()) { 5642 } else if (type_info.IsNonPrimitive()) {
5598 switch (op) { 5643 switch (op) {
5599 case Token::EQ: 5644 case Token::EQ:
5600 case Token::EQ_STRICT: { 5645 case Token::EQ_STRICT: {
5601 AddInstruction(new(zone()) HCheckNonSmi(left)); 5646 AddInstruction(new(zone()) HCheckNonSmi(left));
5602 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); 5647 AddInstruction(HCheckInstanceType::NewIsSpecObject(left));
5603 AddInstruction(new(zone()) HCheckNonSmi(right)); 5648 AddInstruction(new(zone()) HCheckNonSmi(right));
5604 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); 5649 AddInstruction(HCheckInstanceType::NewIsSpecObject(right));
5605 instr = new(zone()) HCompareObjectEq(left, right); 5650 HCompareObjectEqAndBranch* result =
5606 break; 5651 new(zone()) HCompareObjectEqAndBranch(left, right);
5652 result->set_position(expr->position());
5653 return ast_context()->ReturnControl(result, expr->id());
5607 } 5654 }
5608 default: 5655 default:
5609 return Bailout("Unsupported non-primitive compare"); 5656 return Bailout("Unsupported non-primitive compare");
5610 break;
5611 } 5657 }
5612 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && 5658 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) &&
5613 (op == Token::EQ || op == Token::EQ_STRICT)) { 5659 (op == Token::EQ || op == Token::EQ_STRICT)) {
5614 AddInstruction(new(zone()) HCheckNonSmi(left)); 5660 AddInstruction(new(zone()) HCheckNonSmi(left));
5615 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); 5661 AddInstruction(HCheckInstanceType::NewIsSymbol(left));
5616 AddInstruction(new(zone()) HCheckNonSmi(right)); 5662 AddInstruction(new(zone()) HCheckNonSmi(right));
5617 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); 5663 AddInstruction(HCheckInstanceType::NewIsSymbol(right));
5618 instr = new(zone()) HCompareObjectEq(left, right); 5664 HCompareObjectEqAndBranch* result =
5665 new(zone()) HCompareObjectEqAndBranch(left, right);
5666 result->set_position(expr->position());
5667 return ast_context()->ReturnControl(result, expr->id());
5619 } else { 5668 } else {
5620 HCompare* compare = new(zone()) HCompare(left, right, op);
5621 Representation r = ToRepresentation(type_info); 5669 Representation r = ToRepresentation(type_info);
5622 compare->SetInputRepresentation(r); 5670 if (r.IsTagged()) {
5623 instr = compare; 5671 HCompareGeneric* result = new(zone()) HCompareGeneric(left, right, op);
5672 result->set_position(expr->position());
5673 return ast_context()->ReturnInstruction(result, expr->id());
5674 } else {
5675 HCompareIDAndBranch* result =
5676 new(zone()) HCompareIDAndBranch(left, right, op);
5677 result->set_position(expr->position());
5678 result->SetInputRepresentation(r);
5679 return ast_context()->ReturnControl(result, expr->id());
5680 }
5624 } 5681 }
5625 instr->set_position(expr->position());
5626 ast_context()->ReturnInstruction(instr, expr->id());
5627 } 5682 }
5628 5683
5629 5684
5630 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) { 5685 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) {
5631 ASSERT(!HasStackOverflow()); 5686 ASSERT(!HasStackOverflow());
5632 ASSERT(current_block() != NULL); 5687 ASSERT(current_block() != NULL);
5633 ASSERT(current_block()->HasPredecessor()); 5688 ASSERT(current_block()->HasPredecessor());
5634 CHECK_ALIVE(VisitForValue(expr->expression())); 5689 CHECK_ALIVE(VisitForValue(expr->expression()));
5635
5636 HValue* value = Pop(); 5690 HValue* value = Pop();
5637 HIsNull* compare = new(zone()) HIsNull(value, expr->is_strict()); 5691 HIsNullAndBranch* instr =
5638 ast_context()->ReturnInstruction(compare, expr->id()); 5692 new(zone()) HIsNullAndBranch(value, expr->is_strict());
5693 return ast_context()->ReturnControl(instr, expr->id());
5639 } 5694 }
5640 5695
5641 5696
5642 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 5697 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5643 ASSERT(!HasStackOverflow()); 5698 ASSERT(!HasStackOverflow());
5644 ASSERT(current_block() != NULL); 5699 ASSERT(current_block() != NULL);
5645 ASSERT(current_block()->HasPredecessor()); 5700 ASSERT(current_block()->HasPredecessor());
5646 HThisFunction* self = new(zone()) HThisFunction; 5701 HThisFunction* self = new(zone()) HThisFunction;
5647 return ast_context()->ReturnInstruction(self, expr->id()); 5702 return ast_context()->ReturnInstruction(self, expr->id());
5648 } 5703 }
(...skipping 12 matching lines...) Expand all
5661 } 5716 }
5662 } 5717 }
5663 5718
5664 5719
5665 // Generators for inline runtime functions. 5720 // Generators for inline runtime functions.
5666 // Support for types. 5721 // Support for types.
5667 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) { 5722 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) {
5668 ASSERT(call->arguments()->length() == 1); 5723 ASSERT(call->arguments()->length() == 1);
5669 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5724 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5670 HValue* value = Pop(); 5725 HValue* value = Pop();
5671 HIsSmi* result = new(zone()) HIsSmi(value); 5726 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value);
5672 ast_context()->ReturnInstruction(result, call->id()); 5727 return ast_context()->ReturnControl(result, call->id());
5673 } 5728 }
5674 5729
5675 5730
5676 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 5731 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
5677 ASSERT(call->arguments()->length() == 1); 5732 ASSERT(call->arguments()->length() == 1);
5678 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5733 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5679 HValue* value = Pop(); 5734 HValue* value = Pop();
5680 HHasInstanceType* result = 5735 HHasInstanceTypeAndBranch* result =
5681 new(zone()) HHasInstanceType(value, 5736 new(zone()) HHasInstanceTypeAndBranch(value,
5682 FIRST_SPEC_OBJECT_TYPE, 5737 FIRST_SPEC_OBJECT_TYPE,
5683 LAST_SPEC_OBJECT_TYPE); 5738 LAST_SPEC_OBJECT_TYPE);
5684 ast_context()->ReturnInstruction(result, call->id()); 5739 return ast_context()->ReturnControl(result, call->id());
5685 } 5740 }
5686 5741
5687 5742
5688 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) { 5743 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) {
5689 ASSERT(call->arguments()->length() == 1); 5744 ASSERT(call->arguments()->length() == 1);
5690 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5745 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5691 HValue* value = Pop(); 5746 HValue* value = Pop();
5692 HHasInstanceType* result = 5747 HHasInstanceTypeAndBranch* result =
5693 new(zone()) HHasInstanceType(value, JS_FUNCTION_TYPE); 5748 new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE);
5694 ast_context()->ReturnInstruction(result, call->id()); 5749 return ast_context()->ReturnControl(result, call->id());
5695 } 5750 }
5696 5751
5697 5752
5698 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 5753 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
5699 ASSERT(call->arguments()->length() == 1); 5754 ASSERT(call->arguments()->length() == 1);
5700 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5755 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5701 HValue* value = Pop(); 5756 HValue* value = Pop();
5702 HHasCachedArrayIndex* result = new(zone()) HHasCachedArrayIndex(value); 5757 HHasCachedArrayIndexAndBranch* result =
5703 ast_context()->ReturnInstruction(result, call->id()); 5758 new(zone()) HHasCachedArrayIndexAndBranch(value);
5759 return ast_context()->ReturnControl(result, call->id());
5704 } 5760 }
5705 5761
5706 5762
5707 void HGraphBuilder::GenerateIsArray(CallRuntime* call) { 5763 void HGraphBuilder::GenerateIsArray(CallRuntime* call) {
5708 ASSERT(call->arguments()->length() == 1); 5764 ASSERT(call->arguments()->length() == 1);
5709 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5765 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5710 HValue* value = Pop(); 5766 HValue* value = Pop();
5711 HHasInstanceType* result = new(zone()) HHasInstanceType(value, JS_ARRAY_TYPE); 5767 HHasInstanceTypeAndBranch* result =
5712 ast_context()->ReturnInstruction(result, call->id()); 5768 new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE);
5769 return ast_context()->ReturnControl(result, call->id());
5713 } 5770 }
5714 5771
5715 5772
5716 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 5773 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
5717 ASSERT(call->arguments()->length() == 1); 5774 ASSERT(call->arguments()->length() == 1);
5718 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5775 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5719 HValue* value = Pop(); 5776 HValue* value = Pop();
5720 HHasInstanceType* result = 5777 HHasInstanceTypeAndBranch* result =
5721 new(zone()) HHasInstanceType(value, JS_REGEXP_TYPE); 5778 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE);
5722 ast_context()->ReturnInstruction(result, call->id()); 5779 return ast_context()->ReturnControl(result, call->id());
5723 } 5780 }
5724 5781
5725 5782
5726 void HGraphBuilder::GenerateIsObject(CallRuntime* call) { 5783 void HGraphBuilder::GenerateIsObject(CallRuntime* call) {
5727 ASSERT(call->arguments()->length() == 1); 5784 ASSERT(call->arguments()->length() == 1);
5728 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5785 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5729 HValue* value = Pop(); 5786 HValue* value = Pop();
5730 HIsObject* test = new(zone()) HIsObject(value); 5787 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value);
5731 ast_context()->ReturnInstruction(test, call->id()); 5788 return ast_context()->ReturnControl(result, call->id());
5732 } 5789 }
5733 5790
5734 5791
5735 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 5792 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
5736 return Bailout("inlined runtime function: IsNonNegativeSmi"); 5793 return Bailout("inlined runtime function: IsNonNegativeSmi");
5737 } 5794 }
5738 5795
5739 5796
5740 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 5797 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
5741 ASSERT(call->arguments()->length() == 1); 5798 ASSERT(call->arguments()->length() == 1);
5742 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5799 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5743 HValue* value = Pop(); 5800 HValue* value = Pop();
5744 ast_context()->ReturnInstruction(new(zone()) HIsUndetectable(value), 5801 HIsUndetectableAndBranch* result =
5745 call->id()); 5802 new(zone()) HIsUndetectableAndBranch(value);
5803 return ast_context()->ReturnControl(result, call->id());
5746 } 5804 }
5747 5805
5748 5806
5749 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 5807 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
5750 CallRuntime* call) { 5808 CallRuntime* call) {
5751 return Bailout( 5809 return Bailout(
5752 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); 5810 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
5753 } 5811 }
5754 5812
5755 5813
5756 // Support for construct call checks. 5814 // Support for construct call checks.
5757 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 5815 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
5758 ASSERT(call->arguments()->length() == 0); 5816 ASSERT(call->arguments()->length() == 0);
5759 if (function_state()->outer() != NULL) { 5817 if (function_state()->outer() != NULL) {
5760 // We are generating graph for inlined function. Currently 5818 // We are generating graph for inlined function. Currently
5761 // constructor inlining is not supported and we can just return 5819 // constructor inlining is not supported and we can just return
5762 // false from %_IsConstructCall(). 5820 // false from %_IsConstructCall().
5763 ast_context()->ReturnValue(graph()->GetConstantFalse()); 5821 return ast_context()->ReturnValue(graph()->GetConstantFalse());
5764 } else { 5822 } else {
5765 ast_context()->ReturnInstruction(new(zone()) HIsConstructCall, call->id()); 5823 return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch,
5824 call->id());
5766 } 5825 }
5767 } 5826 }
5768 5827
5769 5828
5770 // Support for arguments.length and arguments[?]. 5829 // Support for arguments.length and arguments[?].
5771 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 5830 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
5772 // Our implementation of arguments (based on this stack frame or an 5831 // Our implementation of arguments (based on this stack frame or an
5773 // adapter below it) does not work for inlined functions. This runtime 5832 // adapter below it) does not work for inlined functions. This runtime
5774 // function is blacklisted by AstNode::IsInlineable. 5833 // function is blacklisted by AstNode::IsInlineable.
5775 ASSERT(function_state()->outer() == NULL); 5834 ASSERT(function_state()->outer() == NULL);
5776 ASSERT(call->arguments()->length() == 0); 5835 ASSERT(call->arguments()->length() == 0);
5777 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 5836 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
5778 HArgumentsLength* result = new(zone()) HArgumentsLength(elements); 5837 HArgumentsLength* result = new(zone()) HArgumentsLength(elements);
5779 ast_context()->ReturnInstruction(result, call->id()); 5838 return ast_context()->ReturnInstruction(result, call->id());
5780 } 5839 }
5781 5840
5782 5841
5783 void HGraphBuilder::GenerateArguments(CallRuntime* call) { 5842 void HGraphBuilder::GenerateArguments(CallRuntime* call) {
5784 // Our implementation of arguments (based on this stack frame or an 5843 // Our implementation of arguments (based on this stack frame or an
5785 // adapter below it) does not work for inlined functions. This runtime 5844 // adapter below it) does not work for inlined functions. This runtime
5786 // function is blacklisted by AstNode::IsInlineable. 5845 // function is blacklisted by AstNode::IsInlineable.
5787 ASSERT(function_state()->outer() == NULL); 5846 ASSERT(function_state()->outer() == NULL);
5788 ASSERT(call->arguments()->length() == 1); 5847 ASSERT(call->arguments()->length() == 1);
5789 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5848 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5790 HValue* index = Pop(); 5849 HValue* index = Pop();
5791 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 5850 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
5792 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 5851 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
5793 HAccessArgumentsAt* result = 5852 HAccessArgumentsAt* result =
5794 new(zone()) HAccessArgumentsAt(elements, length, index); 5853 new(zone()) HAccessArgumentsAt(elements, length, index);
5795 ast_context()->ReturnInstruction(result, call->id()); 5854 return ast_context()->ReturnInstruction(result, call->id());
5796 } 5855 }
5797 5856
5798 5857
5799 // Support for accessing the class and value fields of an object. 5858 // Support for accessing the class and value fields of an object.
5800 void HGraphBuilder::GenerateClassOf(CallRuntime* call) { 5859 void HGraphBuilder::GenerateClassOf(CallRuntime* call) {
5801 // The special form detected by IsClassOfTest is detected before we get here 5860 // The special form detected by IsClassOfTest is detected before we get here
5802 // and does not cause a bailout. 5861 // and does not cause a bailout.
5803 return Bailout("inlined runtime function: ClassOf"); 5862 return Bailout("inlined runtime function: ClassOf");
5804 } 5863 }
5805 5864
5806 5865
5807 void HGraphBuilder::GenerateValueOf(CallRuntime* call) { 5866 void HGraphBuilder::GenerateValueOf(CallRuntime* call) {
5808 ASSERT(call->arguments()->length() == 1); 5867 ASSERT(call->arguments()->length() == 1);
5809 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5868 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5810 HValue* value = Pop(); 5869 HValue* value = Pop();
5811 HValueOf* result = new(zone()) HValueOf(value); 5870 HValueOf* result = new(zone()) HValueOf(value);
5812 ast_context()->ReturnInstruction(result, call->id()); 5871 return ast_context()->ReturnInstruction(result, call->id());
5813 } 5872 }
5814 5873
5815 5874
5816 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 5875 void HGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
5817 return Bailout("inlined runtime function: SetValueOf"); 5876 return Bailout("inlined runtime function: SetValueOf");
5818 } 5877 }
5819 5878
5820 5879
5821 // Fast support for charCodeAt(n). 5880 // Fast support for charCodeAt(n).
5822 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 5881 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
5823 ASSERT(call->arguments()->length() == 2); 5882 ASSERT(call->arguments()->length() == 2);
5824 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5883 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5825 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 5884 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5826 HValue* index = Pop(); 5885 HValue* index = Pop();
5827 HValue* string = Pop(); 5886 HValue* string = Pop();
5828 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); 5887 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index);
5829 ast_context()->ReturnInstruction(result, call->id()); 5888 return ast_context()->ReturnInstruction(result, call->id());
5830 } 5889 }
5831 5890
5832 5891
5833 // Fast support for string.charAt(n) and string[n]. 5892 // Fast support for string.charAt(n) and string[n].
5834 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 5893 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
5835 ASSERT(call->arguments()->length() == 1); 5894 ASSERT(call->arguments()->length() == 1);
5836 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5895 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5837 HValue* char_code = Pop(); 5896 HValue* char_code = Pop();
5838 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); 5897 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
5839 ast_context()->ReturnInstruction(result, call->id()); 5898 return ast_context()->ReturnInstruction(result, call->id());
5840 } 5899 }
5841 5900
5842 5901
5843 // Fast support for string.charAt(n) and string[n]. 5902 // Fast support for string.charAt(n) and string[n].
5844 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 5903 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
5845 ASSERT(call->arguments()->length() == 2); 5904 ASSERT(call->arguments()->length() == 2);
5846 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5905 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5847 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 5906 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5848 HValue* index = Pop(); 5907 HValue* index = Pop();
5849 HValue* string = Pop(); 5908 HValue* string = Pop();
5850 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); 5909 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
5851 AddInstruction(char_code); 5910 AddInstruction(char_code);
5852 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); 5911 HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code);
5853 ast_context()->ReturnInstruction(result, call->id()); 5912 return ast_context()->ReturnInstruction(result, call->id());
5854 } 5913 }
5855 5914
5856 5915
5857 // Fast support for object equality testing. 5916 // Fast support for object equality testing.
5858 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 5917 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
5859 ASSERT(call->arguments()->length() == 2); 5918 ASSERT(call->arguments()->length() == 2);
5860 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5919 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5861 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 5920 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5862 HValue* right = Pop(); 5921 HValue* right = Pop();
5863 HValue* left = Pop(); 5922 HValue* left = Pop();
5864 HCompareObjectEq* result = new(zone()) HCompareObjectEq(left, right); 5923 HCompareObjectEqAndBranch* result =
5865 ast_context()->ReturnInstruction(result, call->id()); 5924 new(zone()) HCompareObjectEqAndBranch(left, right);
5925 return ast_context()->ReturnControl(result, call->id());
5866 } 5926 }
5867 5927
5868 5928
5869 void HGraphBuilder::GenerateLog(CallRuntime* call) { 5929 void HGraphBuilder::GenerateLog(CallRuntime* call) {
5870 // %_Log is ignored in optimized code. 5930 // %_Log is ignored in optimized code.
5871 ast_context()->ReturnValue(graph()->GetConstantUndefined()); 5931 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
5872 } 5932 }
5873 5933
5874 5934
5875 // Fast support for Math.random(). 5935 // Fast support for Math.random().
5876 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { 5936 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
5877 return Bailout("inlined runtime function: RandomHeapNumber"); 5937 return Bailout("inlined runtime function: RandomHeapNumber");
5878 } 5938 }
5879 5939
5880 5940
5881 // Fast support for StringAdd. 5941 // Fast support for StringAdd.
5882 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { 5942 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) {
5883 ASSERT_EQ(2, call->arguments()->length()); 5943 ASSERT_EQ(2, call->arguments()->length());
5884 CHECK_ALIVE(VisitArgumentList(call->arguments())); 5944 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5885 HValue* context = environment()->LookupContext(); 5945 HValue* context = environment()->LookupContext();
5886 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); 5946 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2);
5887 Drop(2); 5947 Drop(2);
5888 ast_context()->ReturnInstruction(result, call->id()); 5948 return ast_context()->ReturnInstruction(result, call->id());
5889 } 5949 }
5890 5950
5891 5951
5892 // Fast support for SubString. 5952 // Fast support for SubString.
5893 void HGraphBuilder::GenerateSubString(CallRuntime* call) { 5953 void HGraphBuilder::GenerateSubString(CallRuntime* call) {
5894 ASSERT_EQ(3, call->arguments()->length()); 5954 ASSERT_EQ(3, call->arguments()->length());
5895 CHECK_ALIVE(VisitArgumentList(call->arguments())); 5955 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5896 HValue* context = environment()->LookupContext(); 5956 HValue* context = environment()->LookupContext();
5897 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); 5957 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
5898 Drop(3); 5958 Drop(3);
5899 ast_context()->ReturnInstruction(result, call->id()); 5959 return ast_context()->ReturnInstruction(result, call->id());
5900 } 5960 }
5901 5961
5902 5962
5903 // Fast support for StringCompare. 5963 // Fast support for StringCompare.
5904 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { 5964 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) {
5905 ASSERT_EQ(2, call->arguments()->length()); 5965 ASSERT_EQ(2, call->arguments()->length());
5906 CHECK_ALIVE(VisitArgumentList(call->arguments())); 5966 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5907 HValue* context = environment()->LookupContext(); 5967 HValue* context = environment()->LookupContext();
5908 HCallStub* result = 5968 HCallStub* result =
5909 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); 5969 new(zone()) HCallStub(context, CodeStub::StringCompare, 2);
5910 Drop(2); 5970 Drop(2);
5911 ast_context()->ReturnInstruction(result, call->id()); 5971 return ast_context()->ReturnInstruction(result, call->id());
5912 } 5972 }
5913 5973
5914 5974
5915 // Support for direct calls from JavaScript to native RegExp code. 5975 // Support for direct calls from JavaScript to native RegExp code.
5916 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 5976 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
5917 ASSERT_EQ(4, call->arguments()->length()); 5977 ASSERT_EQ(4, call->arguments()->length());
5918 CHECK_ALIVE(VisitArgumentList(call->arguments())); 5978 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5919 HValue* context = environment()->LookupContext(); 5979 HValue* context = environment()->LookupContext();
5920 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); 5980 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4);
5921 Drop(4); 5981 Drop(4);
5922 ast_context()->ReturnInstruction(result, call->id()); 5982 return ast_context()->ReturnInstruction(result, call->id());
5923 } 5983 }
5924 5984
5925 5985
5926 // Construct a RegExp exec result with two in-object properties. 5986 // Construct a RegExp exec result with two in-object properties.
5927 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 5987 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
5928 ASSERT_EQ(3, call->arguments()->length()); 5988 ASSERT_EQ(3, call->arguments()->length());
5929 CHECK_ALIVE(VisitArgumentList(call->arguments())); 5989 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5930 HValue* context = environment()->LookupContext(); 5990 HValue* context = environment()->LookupContext();
5931 HCallStub* result = 5991 HCallStub* result =
5932 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); 5992 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3);
5933 Drop(3); 5993 Drop(3);
5934 ast_context()->ReturnInstruction(result, call->id()); 5994 return ast_context()->ReturnInstruction(result, call->id());
5935 } 5995 }
5936 5996
5937 5997
5938 // Support for fast native caches. 5998 // Support for fast native caches.
5939 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 5999 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
5940 return Bailout("inlined runtime function: GetFromCache"); 6000 return Bailout("inlined runtime function: GetFromCache");
5941 } 6001 }
5942 6002
5943 6003
5944 // Fast support for number to string. 6004 // Fast support for number to string.
5945 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { 6005 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) {
5946 ASSERT_EQ(1, call->arguments()->length()); 6006 ASSERT_EQ(1, call->arguments()->length());
5947 CHECK_ALIVE(VisitArgumentList(call->arguments())); 6007 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5948 HValue* context = environment()->LookupContext(); 6008 HValue* context = environment()->LookupContext();
5949 HCallStub* result = 6009 HCallStub* result =
5950 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); 6010 new(zone()) HCallStub(context, CodeStub::NumberToString, 1);
5951 Drop(1); 6011 Drop(1);
5952 ast_context()->ReturnInstruction(result, call->id()); 6012 return ast_context()->ReturnInstruction(result, call->id());
5953 } 6013 }
5954 6014
5955 6015
5956 // Fast swapping of elements. Takes three expressions, the object and two 6016 // Fast swapping of elements. Takes three expressions, the object and two
5957 // indices. This should only be used if the indices are known to be 6017 // indices. This should only be used if the indices are known to be
5958 // non-negative and within bounds of the elements array at the call site. 6018 // non-negative and within bounds of the elements array at the call site.
5959 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { 6019 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) {
5960 return Bailout("inlined runtime function: SwapElements"); 6020 return Bailout("inlined runtime function: SwapElements");
5961 } 6021 }
5962 6022
5963 6023
5964 // Fast call for custom callbacks. 6024 // Fast call for custom callbacks.
5965 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { 6025 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) {
5966 // 1 ~ The function to call is not itself an argument to the call. 6026 // 1 ~ The function to call is not itself an argument to the call.
5967 int arg_count = call->arguments()->length() - 1; 6027 int arg_count = call->arguments()->length() - 1;
5968 ASSERT(arg_count >= 1); // There's always at least a receiver. 6028 ASSERT(arg_count >= 1); // There's always at least a receiver.
5969 6029
5970 for (int i = 0; i < arg_count; ++i) { 6030 for (int i = 0; i < arg_count; ++i) {
5971 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); 6031 CHECK_ALIVE(VisitArgument(call->arguments()->at(i)));
5972 } 6032 }
5973 CHECK_ALIVE(VisitForValue(call->arguments()->last())); 6033 CHECK_ALIVE(VisitForValue(call->arguments()->last()));
5974 HValue* function = Pop(); 6034 HValue* function = Pop();
5975 HValue* context = environment()->LookupContext(); 6035 HValue* context = environment()->LookupContext();
5976 HInvokeFunction* result = 6036 HInvokeFunction* result =
5977 new(zone()) HInvokeFunction(context, function, arg_count); 6037 new(zone()) HInvokeFunction(context, function, arg_count);
5978 Drop(arg_count); 6038 Drop(arg_count);
5979 ast_context()->ReturnInstruction(result, call->id()); 6039 return ast_context()->ReturnInstruction(result, call->id());
5980 } 6040 }
5981 6041
5982 6042
5983 // Fast call to math functions. 6043 // Fast call to math functions.
5984 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { 6044 void HGraphBuilder::GenerateMathPow(CallRuntime* call) {
5985 ASSERT_EQ(2, call->arguments()->length()); 6045 ASSERT_EQ(2, call->arguments()->length());
5986 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 6046 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5987 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 6047 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5988 HValue* right = Pop(); 6048 HValue* right = Pop();
5989 HValue* left = Pop(); 6049 HValue* left = Pop();
5990 HPower* result = new(zone()) HPower(left, right); 6050 HPower* result = new(zone()) HPower(left, right);
5991 ast_context()->ReturnInstruction(result, call->id()); 6051 return ast_context()->ReturnInstruction(result, call->id());
5992 } 6052 }
5993 6053
5994 6054
5995 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { 6055 void HGraphBuilder::GenerateMathSin(CallRuntime* call) {
5996 ASSERT_EQ(1, call->arguments()->length()); 6056 ASSERT_EQ(1, call->arguments()->length());
5997 CHECK_ALIVE(VisitArgumentList(call->arguments())); 6057 CHECK_ALIVE(VisitArgumentList(call->arguments()));
5998 HValue* context = environment()->LookupContext(); 6058 HValue* context = environment()->LookupContext();
5999 HCallStub* result = 6059 HCallStub* result =
6000 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 6060 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
6001 result->set_transcendental_type(TranscendentalCache::SIN); 6061 result->set_transcendental_type(TranscendentalCache::SIN);
6002 Drop(1); 6062 Drop(1);
6003 ast_context()->ReturnInstruction(result, call->id()); 6063 return ast_context()->ReturnInstruction(result, call->id());
6004 } 6064 }
6005 6065
6006 6066
6007 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { 6067 void HGraphBuilder::GenerateMathCos(CallRuntime* call) {
6008 ASSERT_EQ(1, call->arguments()->length()); 6068 ASSERT_EQ(1, call->arguments()->length());
6009 CHECK_ALIVE(VisitArgumentList(call->arguments())); 6069 CHECK_ALIVE(VisitArgumentList(call->arguments()));
6010 HValue* context = environment()->LookupContext(); 6070 HValue* context = environment()->LookupContext();
6011 HCallStub* result = 6071 HCallStub* result =
6012 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 6072 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
6013 result->set_transcendental_type(TranscendentalCache::COS); 6073 result->set_transcendental_type(TranscendentalCache::COS);
6014 Drop(1); 6074 Drop(1);
6015 ast_context()->ReturnInstruction(result, call->id()); 6075 return ast_context()->ReturnInstruction(result, call->id());
6016 } 6076 }
6017 6077
6018 6078
6019 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { 6079 void HGraphBuilder::GenerateMathLog(CallRuntime* call) {
6020 ASSERT_EQ(1, call->arguments()->length()); 6080 ASSERT_EQ(1, call->arguments()->length());
6021 CHECK_ALIVE(VisitArgumentList(call->arguments())); 6081 CHECK_ALIVE(VisitArgumentList(call->arguments()));
6022 HValue* context = environment()->LookupContext(); 6082 HValue* context = environment()->LookupContext();
6023 HCallStub* result = 6083 HCallStub* result =
6024 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); 6084 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
6025 result->set_transcendental_type(TranscendentalCache::LOG); 6085 result->set_transcendental_type(TranscendentalCache::LOG);
6026 Drop(1); 6086 Drop(1);
6027 ast_context()->ReturnInstruction(result, call->id()); 6087 return ast_context()->ReturnInstruction(result, call->id());
6028 } 6088 }
6029 6089
6030 6090
6031 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 6091 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
6032 return Bailout("inlined runtime function: MathSqrt"); 6092 return Bailout("inlined runtime function: MathSqrt");
6033 } 6093 }
6034 6094
6035 6095
6036 // Check whether two RegExps are equivalent 6096 // Check whether two RegExps are equivalent
6037 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 6097 void HGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
6038 return Bailout("inlined runtime function: IsRegExpEquivalent"); 6098 return Bailout("inlined runtime function: IsRegExpEquivalent");
6039 } 6099 }
6040 6100
6041 6101
6042 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 6102 void HGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
6043 ASSERT(call->arguments()->length() == 1); 6103 ASSERT(call->arguments()->length() == 1);
6044 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 6104 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
6045 HValue* value = Pop(); 6105 HValue* value = Pop();
6046 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); 6106 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value);
6047 ast_context()->ReturnInstruction(result, call->id()); 6107 return ast_context()->ReturnInstruction(result, call->id());
6048 } 6108 }
6049 6109
6050 6110
6051 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 6111 void HGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
6052 return Bailout("inlined runtime function: FastAsciiArrayJoin"); 6112 return Bailout("inlined runtime function: FastAsciiArrayJoin");
6053 } 6113 }
6054 6114
6055 6115
6056 #undef CHECK_BAILOUT 6116 #undef CHECK_BAILOUT
6057 #undef CHECK_ALIVE 6117 #undef CHECK_ALIVE
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
6577 } 6637 }
6578 } 6638 }
6579 6639
6580 #ifdef DEBUG 6640 #ifdef DEBUG
6581 if (graph_ != NULL) graph_->Verify(); 6641 if (graph_ != NULL) graph_->Verify();
6582 if (allocator_ != NULL) allocator_->Verify(); 6642 if (allocator_ != NULL) allocator_->Verify();
6583 #endif 6643 #endif
6584 } 6644 }
6585 6645
6586 } } // namespace v8::internal 6646 } } // namespace v8::internal
OLDNEW
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698