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

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: fixed bug in LBranch 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 // The value is tracked in the bailout environment, and communicated 2057 // The value is tracked in the bailout environment, and communicated
2067 // through the environment as the result of the expression. 2058 // through the environment as the result of the expression.
2068 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { 2059 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) {
2069 owner()->Bailout("bad value context for arguments value"); 2060 owner()->Bailout("bad value context for arguments value");
2070 } 2061 }
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, new HTest(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) {
Kevin Millikin (Chromium) 2011/06/30 10:52:03 An alternative that I like better is to add a meth
fschneider 2011/06/30 13:13:36 Done.
2081 owner()->AddInstruction(instr); 2072 if (!instr->IsControlInstruction()) {
2082 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); 2073 owner()->AddInstruction(instr);
2074 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id);
2075 } else {
2076 ASSERT(!instr->HasSideEffects());
2077 owner()->MaterializeBoolean(HControlInstruction::cast(instr), ast_id);
Kevin Millikin (Chromium) 2011/06/30 10:52:03 I wonder why it is necessary to materialize anythi
fschneider 2011/06/30 13:13:36 Done. Removed MaterializeBoolean.
2078 }
2083 } 2079 }
2084 2080
2085 2081
2086 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { 2082 void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) {
2087 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 2083 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
2088 owner()->Bailout("bad value context for arguments object value"); 2084 return owner()->Bailout("bad value context for arguments object value");
2089 } 2085 }
2090 owner()->AddInstruction(instr); 2086 if (!instr->IsControlInstruction()) {
2091 owner()->Push(instr); 2087 owner()->AddInstruction(instr);
2092 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); 2088 owner()->Push(instr);
2089 if (instr->HasSideEffects()) owner()->AddSimulate(ast_id);
2090 } else {
2091 ASSERT(!instr->HasSideEffects());
2092 owner()->MaterializeBoolean(HControlInstruction::cast(instr), ast_id);
2093 }
2093 } 2094 }
2094 2095
2095 2096
2096 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { 2097 void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) {
2097 HGraphBuilder* builder = owner(); 2098 if (!instr->IsControlInstruction()) {
2098 builder->AddInstruction(instr); 2099 HGraphBuilder* builder = owner();
2099 // We expect a simulate after every expression with side effects, though 2100 builder->AddInstruction(instr);
2100 // this one isn't actually needed (and wouldn't work if it were targeted). 2101 // We expect a simulate after every expression with side effects, though
2101 if (instr->HasSideEffects()) { 2102 // this one isn't actually needed (and wouldn't work if it were targeted).
2102 builder->Push(instr); 2103 if (instr->HasSideEffects()) {
2103 builder->AddSimulate(ast_id); 2104 builder->Push(instr);
2104 builder->Pop(); 2105 builder->AddSimulate(ast_id);
2106 builder->Pop();
2107 }
2108 BuildBranch(instr, new HTest(instr));
2109 } else {
2110 BuildBranch(NULL, HControlInstruction::cast(instr));
2105 } 2111 }
2106 BuildBranch(instr);
2107 } 2112 }
2108 2113
2109 2114
2110 void TestContext::BuildBranch(HValue* value) { 2115 void TestContext::BuildBranch(HValue* value, HControlInstruction* test) {
Kevin Millikin (Chromium) 2011/06/30 10:52:03 This is trying to do too much. It's strange that
fschneider 2011/06/30 13:13:36 Done.
2111 // We expect the graph to be in edge-split form: there is no edge that 2116 // 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 2117 // 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 2118 // property by always adding an empty block on the outgoing edges of this
2114 // branch. 2119 // branch.
2115 HGraphBuilder* builder = owner(); 2120 HGraphBuilder* builder = owner();
2116 if (value->CheckFlag(HValue::kIsArguments)) { 2121 ASSERT(value == NULL || !value->IsControlInstruction());
2122 if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
2117 builder->Bailout("arguments object value in a test context"); 2123 builder->Bailout("arguments object value in a test context");
2118 } 2124 }
2119 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 2125 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
2120 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 2126 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
2121 HTest* test = new(zone()) HTest(value, empty_true, empty_false); 2127 test->SetSuccessorAt(0, empty_true);
2128 test->SetSuccessorAt(1, empty_false);
2122 builder->current_block()->Finish(test); 2129 builder->current_block()->Finish(test);
2123 2130
2124 empty_true->Goto(if_true()); 2131 empty_true->Goto(if_true());
2125 empty_false->Goto(if_false()); 2132 empty_false->Goto(if_false());
2126 builder->set_current_block(NULL); 2133 builder->set_current_block(NULL);
2127 } 2134 }
2128 2135
2129 2136
2130 // HGraphBuilder infrastructure for bailing out and checking bailouts. 2137 // HGraphBuilder infrastructure for bailing out and checking bailouts.
2131 #define CHECK_BAILOUT(call) \ 2138 #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 2624 // Finish with deoptimize and add uses of enviroment values to
2618 // account for invisible uses. 2625 // account for invisible uses.
2619 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); 2626 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
2620 set_current_block(NULL); 2627 set_current_block(NULL);
2621 break; 2628 break;
2622 } 2629 }
2623 2630
2624 // Otherwise generate a compare and branch. 2631 // Otherwise generate a compare and branch.
2625 CHECK_ALIVE(VisitForValue(clause->label())); 2632 CHECK_ALIVE(VisitForValue(clause->label()));
2626 HValue* label_value = Pop(); 2633 HValue* label_value = Pop();
2627 HCompare* compare = 2634 HCompareIDAndBranch* compare =
2628 new(zone()) HCompare(tag_value, label_value, Token::EQ_STRICT); 2635 new(zone()) HCompareIDAndBranch(tag_value,
2636 label_value,
2637 Token::EQ_STRICT);
2629 compare->SetInputRepresentation(Representation::Integer32()); 2638 compare->SetInputRepresentation(Representation::Integer32());
2630 ASSERT(!compare->HasSideEffects());
2631 AddInstruction(compare);
2632 HBasicBlock* body_block = graph()->CreateBasicBlock(); 2639 HBasicBlock* body_block = graph()->CreateBasicBlock();
2633 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 2640 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
2634 HTest* branch = new(zone()) HTest(compare, body_block, next_test_block); 2641 compare->SetSuccessorAt(0, body_block);
2635 current_block()->Finish(branch); 2642 compare->SetSuccessorAt(1, next_test_block);
2643 current_block()->Finish(compare);
2636 set_current_block(next_test_block); 2644 set_current_block(next_test_block);
2637 } 2645 }
2638 2646
2639 // Save the current block to use for the default or to join with the 2647 // Save the current block to use for the default or to join with the
2640 // exit. This block is NULL if we deoptimized. 2648 // exit. This block is NULL if we deoptimized.
2641 HBasicBlock* last_block = current_block(); 2649 HBasicBlock* last_block = current_block();
2642 2650
2643 // 2. Loop over the clauses and the linked list of tests in lockstep, 2651 // 2. Loop over the clauses and the linked list of tests in lockstep,
2644 // translating the clause bodies. 2652 // translating the clause bodies.
2645 HBasicBlock* curr_test_block = first_test_block; 2653 HBasicBlock* curr_test_block = first_test_block;
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
3948 elements->ClearFlag(HValue::kUseGVN); 3956 elements->ClearFlag(HValue::kUseGVN);
3949 HInstruction* length = 3957 HInstruction* length =
3950 AddInstruction(new(zone()) HExternalArrayLength(elements)); 3958 AddInstruction(new(zone()) HExternalArrayLength(elements));
3951 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 3959 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3952 external_elements = new(zone()) HLoadExternalArrayPointer(elements); 3960 external_elements = new(zone()) HLoadExternalArrayPointer(elements);
3953 AddInstruction(external_elements); 3961 AddInstruction(external_elements);
3954 } 3962 }
3955 if (type_todo[elements_kind]) { 3963 if (type_todo[elements_kind]) {
3956 HBasicBlock* if_true = graph()->CreateBasicBlock(); 3964 HBasicBlock* if_true = graph()->CreateBasicBlock();
3957 HBasicBlock* if_false = graph()->CreateBasicBlock(); 3965 HBasicBlock* if_false = graph()->CreateBasicBlock();
3958 HCompareConstantEq* compare = new(zone()) HCompareConstantEq( 3966 HCompareConstantEqAndBranch* compare =
3959 elements_kind_instr, 3967 new(zone()) HCompareConstantEqAndBranch(elements_kind_instr,
3960 elements_kind, 3968 elements_kind,
3961 Token::EQ_STRICT); 3969 Token::EQ_STRICT);
3962 AddInstruction(compare); 3970 compare->SetSuccessorAt(0, if_true);
3963 HTest* branch = new(zone()) HTest(compare, if_true, if_false); 3971 compare->SetSuccessorAt(1, if_false);
3964 current_block()->Finish(branch); 3972 current_block()->Finish(compare);
3965 3973
3966 set_current_block(if_true); 3974 set_current_block(if_true);
3967 HInstruction* access; 3975 HInstruction* access;
3968 if (elements_kind == JSObject::FAST_ELEMENTS) { 3976 if (elements_kind == JSObject::FAST_ELEMENTS) {
3969 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 3977 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
3970 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 3978 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
3971 HInstruction* typecheck = 3979 HHasInstanceTypeAndBranch* typecheck =
3972 AddInstruction(new(zone()) HHasInstanceType(object, JS_ARRAY_TYPE)); 3980 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
3973 HTest* test = new(zone()) HTest(typecheck, if_jsarray, if_fastobject); 3981 typecheck->SetSuccessorAt(0, if_jsarray);
3974 current_block()->Finish(test); 3982 typecheck->SetSuccessorAt(1, if_fastobject);
3983 current_block()->Finish(typecheck);
3975 3984
3976 set_current_block(if_jsarray); 3985 set_current_block(if_jsarray);
3977 HInstruction* length = new(zone()) HJSArrayLength(object); 3986 HInstruction* length = new(zone()) HJSArrayLength(object);
3978 AddInstruction(length); 3987 AddInstruction(length);
3979 length->ClearFlag(HValue::kUseGVN); 3988 length->ClearFlag(HValue::kUseGVN);
3980 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 3989 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3981 elements = AddInstruction(new(zone()) HLoadElements(object)); 3990 elements = AddInstruction(new(zone()) HLoadElements(object));
3982 elements->ClearFlag(HValue::kUseGVN); 3991 elements->ClearFlag(HValue::kUseGVN);
3983 if (is_store) { 3992 if (is_store) {
3984 access = AddInstruction( 3993 access = AddInstruction(
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
5487 if (info.IsNumber()) return Representation::Double(); 5496 if (info.IsNumber()) return Representation::Double();
5488 return Representation::Tagged(); 5497 return Representation::Tagged();
5489 } 5498 }
5490 5499
5491 5500
5492 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* compare_expr, 5501 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* compare_expr,
5493 Expression* expr, 5502 Expression* expr,
5494 Handle<String> check) { 5503 Handle<String> check) {
5495 CHECK_ALIVE(VisitForTypeOf(expr)); 5504 CHECK_ALIVE(VisitForTypeOf(expr));
5496 HValue* expr_value = Pop(); 5505 HValue* expr_value = Pop();
5497 HInstruction* instr = new(zone()) HTypeofIs(expr_value, check); 5506 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(expr_value, check);
5498 instr->set_position(compare_expr->position()); 5507 instr->set_position(compare_expr->position());
5499 ast_context()->ReturnInstruction(instr, compare_expr->id()); 5508 ast_context()->ReturnInstruction(instr, compare_expr->id());
5500 } 5509 }
5501 5510
5502 5511
5503 void HGraphBuilder::HandleLiteralCompareUndefined( 5512 void HGraphBuilder::HandleLiteralCompareUndefined(
5504 CompareOperation* compare_expr, Expression* expr) { 5513 CompareOperation* compare_expr, Expression* expr) {
5505 CHECK_ALIVE(VisitForValue(expr)); 5514 CHECK_ALIVE(VisitForValue(expr));
5506 HValue* lhs = Pop(); 5515 HValue* lhs = Pop();
5507 HValue* rhs = graph()->GetConstantUndefined(); 5516 HValue* rhs = graph()->GetConstantUndefined();
5508 HInstruction* instr = 5517 HCompareObjectEqAndBranch* instr =
5509 new(zone()) HCompareObjectEq(lhs, rhs); 5518 new(zone()) HCompareObjectEqAndBranch(lhs, rhs);
5510 instr->set_position(compare_expr->position()); 5519 instr->set_position(compare_expr->position());
5511 ast_context()->ReturnInstruction(instr, compare_expr->id()); 5520 ast_context()->ReturnInstruction(instr, compare_expr->id());
5512 } 5521 }
5513 5522
5514 5523
5515 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 5524 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
5516 ASSERT(!HasStackOverflow()); 5525 ASSERT(!HasStackOverflow());
5517 ASSERT(current_block() != NULL); 5526 ASSERT(current_block() != NULL);
5518 ASSERT(current_block()->HasPredecessor()); 5527 ASSERT(current_block()->HasPredecessor());
5519 if (IsClassOfTest(expr)) { 5528 if (IsClassOfTest(expr)) {
5520 CallRuntime* call = expr->left()->AsCallRuntime(); 5529 CallRuntime* call = expr->left()->AsCallRuntime();
5530 ASSERT(call->arguments()->length() == 1);
5521 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5531 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5522 HValue* value = Pop(); 5532 HValue* value = Pop();
5523 Literal* literal = expr->right()->AsLiteral(); 5533 Literal* literal = expr->right()->AsLiteral();
5524 Handle<String> rhs = Handle<String>::cast(literal->handle()); 5534 Handle<String> rhs = Handle<String>::cast(literal->handle());
5525 HInstruction* instr = new(zone()) HClassOfTest(value, rhs); 5535 HClassOfTestAndBranch* instr =
5536 new(zone()) HClassOfTestAndBranch(value, rhs);
5526 instr->set_position(expr->position()); 5537 instr->set_position(expr->position());
5527 ast_context()->ReturnInstruction(instr, expr->id()); 5538 ast_context()->ReturnInstruction(instr, expr->id());
5528 return; 5539 return;
5529 } 5540 }
5530 5541
5531 // Check for special cases that compare against literals. 5542 // Check for special cases that compare against literals.
5532 Expression *sub_expr; 5543 Expression *sub_expr;
5533 Handle<String> check; 5544 Handle<String> check;
5534 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 5545 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
5535 HandleLiteralCompareTypeof(expr, sub_expr, check); 5546 HandleLiteralCompareTypeof(expr, sub_expr, check);
(...skipping 13 matching lines...) Expand all
5549 type_info = TypeInfo::Unknown(); 5560 type_info = TypeInfo::Unknown();
5550 } 5561 }
5551 5562
5552 CHECK_ALIVE(VisitForValue(expr->left())); 5563 CHECK_ALIVE(VisitForValue(expr->left()));
5553 CHECK_ALIVE(VisitForValue(expr->right())); 5564 CHECK_ALIVE(VisitForValue(expr->right()));
5554 5565
5555 HValue* right = Pop(); 5566 HValue* right = Pop();
5556 HValue* left = Pop(); 5567 HValue* left = Pop();
5557 Token::Value op = expr->op(); 5568 Token::Value op = expr->op();
5558 5569
5559 HInstruction* instr = NULL;
5560 if (op == Token::INSTANCEOF) { 5570 if (op == Token::INSTANCEOF) {
5561 // Check to see if the rhs of the instanceof is a global function not 5571 // 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 5572 // residing in new space. If it is we assume that the function will stay the
5563 // same. 5573 // same.
5564 Handle<JSFunction> target = Handle<JSFunction>::null(); 5574 Handle<JSFunction> target = Handle<JSFunction>::null();
5565 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); 5575 Variable* var = expr->right()->AsVariableProxy()->AsVariable();
5566 bool global_function = (var != NULL) && var->is_global() && !var->is_this(); 5576 bool global_function = (var != NULL) && var->is_global() && !var->is_this();
5567 if (global_function && 5577 if (global_function &&
5568 info()->has_global_object() && 5578 info()->has_global_object() &&
5569 !info()->global_object()->IsAccessCheckNeeded()) { 5579 !info()->global_object()->IsAccessCheckNeeded()) {
(...skipping 10 matching lines...) Expand all
5580 if (!isolate()->heap()->InNewSpace(*candidate)) { 5590 if (!isolate()->heap()->InNewSpace(*candidate)) {
5581 target = candidate; 5591 target = candidate;
5582 } 5592 }
5583 } 5593 }
5584 } 5594 }
5585 5595
5586 // If the target is not null we have found a known global function that is 5596 // If the target is not null we have found a known global function that is
5587 // assumed to stay the same for this instanceof. 5597 // assumed to stay the same for this instanceof.
5588 if (target.is_null()) { 5598 if (target.is_null()) {
5589 HValue* context = environment()->LookupContext(); 5599 HValue* context = environment()->LookupContext();
5590 instr = new(zone()) HInstanceOf(context, left, right); 5600 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right);
5601 result->set_position(expr->position());
5602 ast_context()->ReturnInstruction(result, expr->id());
Kevin Millikin (Chromium) 2011/06/30 10:52:03 Maybe we should take to writing return ast_contex
fschneider 2011/06/30 13:13:36 Done.
5603 return;
5591 } else { 5604 } else {
5592 AddInstruction(new(zone()) HCheckFunction(right, target)); 5605 AddInstruction(new(zone()) HCheckFunction(right, target));
5593 instr = new(zone()) HInstanceOfKnownGlobal(left, target); 5606 HInstanceOfKnownGlobal* result =
5607 new(zone()) HInstanceOfKnownGlobal(left, target);
5608 result->set_position(expr->position());
5609 ast_context()->ReturnInstruction(result, expr->id());
5610 return;
5594 } 5611 }
5595 } else if (op == Token::IN) { 5612 } else if (op == Token::IN) {
5596 instr = new(zone()) HIn(left, right); 5613 HIn* result = new(zone()) HIn(left, right);
5614 result->set_position(expr->position());
5615 ast_context()->ReturnInstruction(result, expr->id());
5616 return;
5597 } else if (type_info.IsNonPrimitive()) { 5617 } else if (type_info.IsNonPrimitive()) {
5598 switch (op) { 5618 switch (op) {
5599 case Token::EQ: 5619 case Token::EQ:
5600 case Token::EQ_STRICT: { 5620 case Token::EQ_STRICT: {
5601 AddInstruction(new(zone()) HCheckNonSmi(left)); 5621 AddInstruction(new(zone()) HCheckNonSmi(left));
5602 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); 5622 AddInstruction(HCheckInstanceType::NewIsSpecObject(left));
5603 AddInstruction(new(zone()) HCheckNonSmi(right)); 5623 AddInstruction(new(zone()) HCheckNonSmi(right));
5604 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); 5624 AddInstruction(HCheckInstanceType::NewIsSpecObject(right));
5605 instr = new(zone()) HCompareObjectEq(left, right); 5625 HCompareObjectEqAndBranch* result =
5606 break; 5626 new(zone()) HCompareObjectEqAndBranch(left, right);
5627 result->set_position(expr->position());
5628 ast_context()->ReturnInstruction(result, expr->id());
5629 return;
5607 } 5630 }
5608 default: 5631 default:
5609 return Bailout("Unsupported non-primitive compare"); 5632 return Bailout("Unsupported non-primitive compare");
5610 break;
5611 } 5633 }
5612 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && 5634 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) &&
5613 (op == Token::EQ || op == Token::EQ_STRICT)) { 5635 (op == Token::EQ || op == Token::EQ_STRICT)) {
5614 AddInstruction(new(zone()) HCheckNonSmi(left)); 5636 AddInstruction(new(zone()) HCheckNonSmi(left));
5615 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); 5637 AddInstruction(HCheckInstanceType::NewIsSymbol(left));
5616 AddInstruction(new(zone()) HCheckNonSmi(right)); 5638 AddInstruction(new(zone()) HCheckNonSmi(right));
5617 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); 5639 AddInstruction(HCheckInstanceType::NewIsSymbol(right));
5618 instr = new(zone()) HCompareObjectEq(left, right); 5640 HCompareObjectEqAndBranch* result =
5641 new(zone()) HCompareObjectEqAndBranch(left, right);
5642 result->set_position(expr->position());
5643 ast_context()->ReturnInstruction(result, expr->id());
5644 return;
5619 } else { 5645 } else {
5620 HCompare* compare = new(zone()) HCompare(left, right, op);
5621 Representation r = ToRepresentation(type_info); 5646 Representation r = ToRepresentation(type_info);
5622 compare->SetInputRepresentation(r); 5647 if (r.IsTagged()) {
5623 instr = compare; 5648 HCompareGeneric* result = new(zone()) HCompareGeneric(left, right, op);
5649 result->set_position(expr->position());
5650 ast_context()->ReturnInstruction(result, expr->id());
5651 return;
5652 } else {
5653 HCompareIDAndBranch* result =
5654 new(zone()) HCompareIDAndBranch(left, right, op);
5655 result->set_position(expr->position());
5656 result->SetInputRepresentation(r);
5657 ast_context()->ReturnInstruction(result, expr->id());
5658 return;
5659 }
5624 } 5660 }
5625 instr->set_position(expr->position()); 5661 }
5626 ast_context()->ReturnInstruction(instr, expr->id()); 5662
5663
5664 void HGraphBuilder::MaterializeBoolean(HControlInstruction* instr,
Kevin Millikin (Chromium) 2011/06/30 10:52:03 I find this function weird. It should never be ca
fschneider 2011/06/30 13:13:36 Removed.
5665 int join_id) {
5666 HBasicBlock* materialize_false = graph()->CreateBasicBlock();
5667 HBasicBlock* materialize_true = graph()->CreateBasicBlock();
5668 instr->SetSuccessorAt(0, materialize_true);
5669 instr->SetSuccessorAt(1, materialize_false);
5670 current_block()->Finish(instr);
5671 set_current_block(materialize_false);
5672 Push(graph()->GetConstantFalse());
5673 set_current_block(materialize_true);
5674 Push(graph()->GetConstantTrue());
5675 HBasicBlock* join =
5676 CreateJoin(materialize_false, materialize_true, join_id);
5677 set_current_block(join);
5678 ast_context()->ReturnValue(Pop());
5627 } 5679 }
5628 5680
5629 5681
5630 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) { 5682 void HGraphBuilder::VisitCompareToNull(CompareToNull* expr) {
5631 ASSERT(!HasStackOverflow()); 5683 ASSERT(!HasStackOverflow());
5632 ASSERT(current_block() != NULL); 5684 ASSERT(current_block() != NULL);
5633 ASSERT(current_block()->HasPredecessor()); 5685 ASSERT(current_block()->HasPredecessor());
5634 CHECK_ALIVE(VisitForValue(expr->expression())); 5686 CHECK_ALIVE(VisitForValue(expr->expression()));
5635
5636 HValue* value = Pop(); 5687 HValue* value = Pop();
5637 HIsNull* compare = new(zone()) HIsNull(value, expr->is_strict()); 5688 HIsNullAndBranch* instr =
5638 ast_context()->ReturnInstruction(compare, expr->id()); 5689 new(zone()) HIsNullAndBranch(value, expr->is_strict());
5690 ast_context()->ReturnInstruction(instr, expr->id());
5639 } 5691 }
5640 5692
5641 5693
5642 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) { 5694 void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
5643 ASSERT(!HasStackOverflow()); 5695 ASSERT(!HasStackOverflow());
5644 ASSERT(current_block() != NULL); 5696 ASSERT(current_block() != NULL);
5645 ASSERT(current_block()->HasPredecessor()); 5697 ASSERT(current_block()->HasPredecessor());
5646 HThisFunction* self = new(zone()) HThisFunction; 5698 HThisFunction* self = new(zone()) HThisFunction;
5647 return ast_context()->ReturnInstruction(self, expr->id()); 5699 return ast_context()->ReturnInstruction(self, expr->id());
5648 } 5700 }
(...skipping 12 matching lines...) Expand all
5661 } 5713 }
5662 } 5714 }
5663 5715
5664 5716
5665 // Generators for inline runtime functions. 5717 // Generators for inline runtime functions.
5666 // Support for types. 5718 // Support for types.
5667 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) { 5719 void HGraphBuilder::GenerateIsSmi(CallRuntime* call) {
5668 ASSERT(call->arguments()->length() == 1); 5720 ASSERT(call->arguments()->length() == 1);
5669 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5721 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5670 HValue* value = Pop(); 5722 HValue* value = Pop();
5671 HIsSmi* result = new(zone()) HIsSmi(value); 5723 HIsSmiAndBranch* result = new(zone()) HIsSmiAndBranch(value);
5672 ast_context()->ReturnInstruction(result, call->id()); 5724 ast_context()->ReturnInstruction(result, call->id());
5673 } 5725 }
5674 5726
5675 5727
5676 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 5728 void HGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
5677 ASSERT(call->arguments()->length() == 1); 5729 ASSERT(call->arguments()->length() == 1);
5678 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5730 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5679 HValue* value = Pop(); 5731 HValue* value = Pop();
5680 HHasInstanceType* result = 5732 HHasInstanceTypeAndBranch* result =
5681 new(zone()) HHasInstanceType(value, 5733 new(zone()) HHasInstanceTypeAndBranch(value,
5682 FIRST_SPEC_OBJECT_TYPE, 5734 FIRST_SPEC_OBJECT_TYPE,
5683 LAST_SPEC_OBJECT_TYPE); 5735 LAST_SPEC_OBJECT_TYPE);
5684 ast_context()->ReturnInstruction(result, call->id()); 5736 ast_context()->ReturnInstruction(result, call->id());
5685 } 5737 }
5686 5738
5687 5739
5688 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) { 5740 void HGraphBuilder::GenerateIsFunction(CallRuntime* call) {
5689 ASSERT(call->arguments()->length() == 1); 5741 ASSERT(call->arguments()->length() == 1);
5690 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5742 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5691 HValue* value = Pop(); 5743 HValue* value = Pop();
5692 HHasInstanceType* result = 5744 HHasInstanceTypeAndBranch* result =
5693 new(zone()) HHasInstanceType(value, JS_FUNCTION_TYPE); 5745 new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE);
5694 ast_context()->ReturnInstruction(result, call->id()); 5746 ast_context()->ReturnInstruction(result, call->id());
5695 } 5747 }
5696 5748
5697 5749
5698 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 5750 void HGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
5699 ASSERT(call->arguments()->length() == 1); 5751 ASSERT(call->arguments()->length() == 1);
5700 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5752 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5701 HValue* value = Pop(); 5753 HValue* value = Pop();
5702 HHasCachedArrayIndex* result = new(zone()) HHasCachedArrayIndex(value); 5754 HHasCachedArrayIndexAndBranch* result =
5755 new(zone()) HHasCachedArrayIndexAndBranch(value);
5703 ast_context()->ReturnInstruction(result, call->id()); 5756 ast_context()->ReturnInstruction(result, call->id());
5704 } 5757 }
5705 5758
5706 5759
5707 void HGraphBuilder::GenerateIsArray(CallRuntime* call) { 5760 void HGraphBuilder::GenerateIsArray(CallRuntime* call) {
5708 ASSERT(call->arguments()->length() == 1); 5761 ASSERT(call->arguments()->length() == 1);
5709 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5762 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5710 HValue* value = Pop(); 5763 HValue* value = Pop();
5711 HHasInstanceType* result = new(zone()) HHasInstanceType(value, JS_ARRAY_TYPE); 5764 HHasInstanceTypeAndBranch* result =
5765 new(zone()) HHasInstanceTypeAndBranch(value, JS_ARRAY_TYPE);
5712 ast_context()->ReturnInstruction(result, call->id()); 5766 ast_context()->ReturnInstruction(result, call->id());
5713 } 5767 }
5714 5768
5715 5769
5716 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 5770 void HGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
5717 ASSERT(call->arguments()->length() == 1); 5771 ASSERT(call->arguments()->length() == 1);
5718 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5772 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5719 HValue* value = Pop(); 5773 HValue* value = Pop();
5720 HHasInstanceType* result = 5774 HHasInstanceTypeAndBranch* result =
5721 new(zone()) HHasInstanceType(value, JS_REGEXP_TYPE); 5775 new(zone()) HHasInstanceTypeAndBranch(value, JS_REGEXP_TYPE);
5722 ast_context()->ReturnInstruction(result, call->id()); 5776 ast_context()->ReturnInstruction(result, call->id());
5723 } 5777 }
5724 5778
5725 5779
5726 void HGraphBuilder::GenerateIsObject(CallRuntime* call) { 5780 void HGraphBuilder::GenerateIsObject(CallRuntime* call) {
5727 ASSERT(call->arguments()->length() == 1); 5781 ASSERT(call->arguments()->length() == 1);
5728 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5782 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5729 HValue* value = Pop(); 5783 HValue* value = Pop();
5730 HIsObject* test = new(zone()) HIsObject(value); 5784 HIsObjectAndBranch* result = new(zone()) HIsObjectAndBranch(value);
5731 ast_context()->ReturnInstruction(test, call->id()); 5785 ast_context()->ReturnInstruction(result, call->id());
5732 } 5786 }
5733 5787
5734 5788
5735 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 5789 void HGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
5736 return Bailout("inlined runtime function: IsNonNegativeSmi"); 5790 return Bailout("inlined runtime function: IsNonNegativeSmi");
5737 } 5791 }
5738 5792
5739 5793
5740 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 5794 void HGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
5741 ASSERT(call->arguments()->length() == 1); 5795 ASSERT(call->arguments()->length() == 1);
5742 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5796 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5743 HValue* value = Pop(); 5797 HValue* value = Pop();
5744 ast_context()->ReturnInstruction(new(zone()) HIsUndetectable(value), 5798 HIsUndetectableAndBranch* result =
5745 call->id()); 5799 new(zone()) HIsUndetectableAndBranch(value);
5800 ast_context()->ReturnInstruction(result, call->id());
5746 } 5801 }
5747 5802
5748 5803
5749 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 5804 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
5750 CallRuntime* call) { 5805 CallRuntime* call) {
5751 return Bailout( 5806 return Bailout(
5752 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); 5807 "inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
5753 } 5808 }
5754 5809
5755 5810
5756 // Support for construct call checks. 5811 // Support for construct call checks.
5757 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 5812 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
5758 ASSERT(call->arguments()->length() == 0); 5813 ASSERT(call->arguments()->length() == 0);
5759 if (function_state()->outer() != NULL) { 5814 if (function_state()->outer() != NULL) {
5760 // We are generating graph for inlined function. Currently 5815 // We are generating graph for inlined function. Currently
5761 // constructor inlining is not supported and we can just return 5816 // constructor inlining is not supported and we can just return
5762 // false from %_IsConstructCall(). 5817 // false from %_IsConstructCall().
5763 ast_context()->ReturnValue(graph()->GetConstantFalse()); 5818 ast_context()->ReturnValue(graph()->GetConstantFalse());
5764 } else { 5819 } else {
5765 ast_context()->ReturnInstruction(new(zone()) HIsConstructCall, call->id()); 5820 ast_context()->ReturnInstruction(new(zone()) HIsConstructCallAndBranch,
5821 call->id());
5766 } 5822 }
5767 } 5823 }
5768 5824
5769 5825
5770 // Support for arguments.length and arguments[?]. 5826 // Support for arguments.length and arguments[?].
5771 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 5827 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
5772 // Our implementation of arguments (based on this stack frame or an 5828 // Our implementation of arguments (based on this stack frame or an
5773 // adapter below it) does not work for inlined functions. This runtime 5829 // adapter below it) does not work for inlined functions. This runtime
5774 // function is blacklisted by AstNode::IsInlineable. 5830 // function is blacklisted by AstNode::IsInlineable.
5775 ASSERT(function_state()->outer() == NULL); 5831 ASSERT(function_state()->outer() == NULL);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5854 } 5910 }
5855 5911
5856 5912
5857 // Fast support for object equality testing. 5913 // Fast support for object equality testing.
5858 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 5914 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
5859 ASSERT(call->arguments()->length() == 2); 5915 ASSERT(call->arguments()->length() == 2);
5860 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 5916 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
5861 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 5917 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
5862 HValue* right = Pop(); 5918 HValue* right = Pop();
5863 HValue* left = Pop(); 5919 HValue* left = Pop();
5864 HCompareObjectEq* result = new(zone()) HCompareObjectEq(left, right); 5920 HCompareObjectEqAndBranch* result =
5921 new(zone()) HCompareObjectEqAndBranch(left, right);
5865 ast_context()->ReturnInstruction(result, call->id()); 5922 ast_context()->ReturnInstruction(result, call->id());
5866 } 5923 }
5867 5924
5868 5925
5869 void HGraphBuilder::GenerateLog(CallRuntime* call) { 5926 void HGraphBuilder::GenerateLog(CallRuntime* call) {
5870 // %_Log is ignored in optimized code. 5927 // %_Log is ignored in optimized code.
5871 ast_context()->ReturnValue(graph()->GetConstantUndefined()); 5928 ast_context()->ReturnValue(graph()->GetConstantUndefined());
5872 } 5929 }
5873 5930
5874 5931
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
6577 } 6634 }
6578 } 6635 }
6579 6636
6580 #ifdef DEBUG 6637 #ifdef DEBUG
6581 if (graph_ != NULL) graph_->Verify(); 6638 if (graph_ != NULL) graph_->Verify();
6582 if (allocator_ != NULL) allocator_->Verify(); 6639 if (allocator_ != NULL) allocator_->Verify();
6583 #endif 6640 #endif
6584 } 6641 }
6585 6642
6586 } } // namespace v8::internal 6643 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698