OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
556 Scope* scope = info()->scope(); | 556 Scope* scope = info()->scope(); |
557 | 557 |
558 // Build the arguments object if it is used. | 558 // Build the arguments object if it is used. |
559 BuildArgumentsObject(scope->arguments()); | 559 BuildArgumentsObject(scope->arguments()); |
560 | 560 |
561 // Build rest arguments array if it is used. | 561 // Build rest arguments array if it is used. |
562 int rest_index; | 562 int rest_index; |
563 Variable* rest_parameter = scope->rest_parameter(&rest_index); | 563 Variable* rest_parameter = scope->rest_parameter(&rest_index); |
564 BuildRestArgumentsArray(rest_parameter, rest_index); | 564 BuildRestArgumentsArray(rest_parameter, rest_index); |
565 | 565 |
566 if (scope->this_function_var() != nullptr || | 566 // Build .this_function var if it is used. |
567 scope->new_target_var() != nullptr) { | 567 BuildThisFunctionVar(scope->this_function_var()); |
568 | |
569 if (scope->new_target_var() != nullptr) { | |
568 SetStackOverflow(); | 570 SetStackOverflow(); |
569 } | 571 } |
570 | 572 |
571 // Emit tracing call if requested to do so. | 573 // Emit tracing call if requested to do so. |
572 if (FLAG_trace) { | 574 if (FLAG_trace) { |
573 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); | 575 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); |
574 } | 576 } |
575 | 577 |
576 // Visit illegal re-declaration and bail out if it exists. | 578 // Visit illegal re-declaration and bail out if it exists. |
577 if (scope->HasIllegalRedeclaration()) { | 579 if (scope->HasIllegalRedeclaration()) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
623 replacer.MarkPermanentlyLive(arguments->index()); | 625 replacer.MarkPermanentlyLive(arguments->index()); |
624 } | 626 } |
625 liveness_analyzer()->Run(&replacer); | 627 liveness_analyzer()->Run(&replacer); |
626 if (FLAG_trace_environment_liveness) { | 628 if (FLAG_trace_environment_liveness) { |
627 OFStream os(stdout); | 629 OFStream os(stdout); |
628 liveness_analyzer()->Print(os); | 630 liveness_analyzer()->Print(os); |
629 } | 631 } |
630 } | 632 } |
631 | 633 |
632 | 634 |
633 // Left-hand side can only be a property, a global or a variable slot. | |
634 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | |
635 | |
636 | |
637 // Determine the left-hand side kind of an assignment. | |
638 static LhsKind DetermineLhsKind(Expression* expr) { | |
639 Property* property = expr->AsProperty(); | |
640 DCHECK(expr->IsValidReferenceExpression()); | |
641 LhsKind lhs_kind = | |
642 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) | |
643 ? NAMED_PROPERTY | |
644 : KEYED_PROPERTY; | |
645 return lhs_kind; | |
646 } | |
647 | |
648 | |
649 // Gets the bailout id just before reading a variable proxy, but only for | 635 // Gets the bailout id just before reading a variable proxy, but only for |
650 // unallocated variables. | 636 // unallocated variables. |
651 static BailoutId BeforeId(VariableProxy* proxy) { | 637 static BailoutId BeforeId(VariableProxy* proxy) { |
652 return proxy->var()->location() == Variable::UNALLOCATED ? proxy->BeforeId() | 638 return proxy->var()->location() == Variable::UNALLOCATED ? proxy->BeforeId() |
653 : BailoutId::None(); | 639 : BailoutId::None(); |
654 } | 640 } |
655 | 641 |
656 | 642 |
657 static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) { | 643 static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) { |
658 #if DEBUG | 644 #if DEBUG |
(...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1964 ast_context()->ProduceValue(environment()->Pop()); | 1950 ast_context()->ProduceValue(environment()->Pop()); |
1965 } | 1951 } |
1966 | 1952 |
1967 | 1953 |
1968 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 1954 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
1969 BailoutId bailout_id) { | 1955 BailoutId bailout_id) { |
1970 DCHECK(expr->IsValidReferenceExpression()); | 1956 DCHECK(expr->IsValidReferenceExpression()); |
1971 | 1957 |
1972 // Left-hand side can only be a property, a global or a variable slot. | 1958 // Left-hand side can only be a property, a global or a variable slot. |
1973 Property* property = expr->AsProperty(); | 1959 Property* property = expr->AsProperty(); |
1974 LhsKind assign_type = DetermineLhsKind(expr); | 1960 LhsKind assign_type = Property::GetAssignType(property); |
1975 | 1961 |
1976 // Evaluate LHS expression and store the value. | 1962 // Evaluate LHS expression and store the value. |
1977 switch (assign_type) { | 1963 switch (assign_type) { |
1978 case VARIABLE: { | 1964 case VARIABLE: { |
1979 Variable* var = expr->AsVariableProxy()->var(); | 1965 Variable* var = expr->AsVariableProxy()->var(); |
1980 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 1966 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
1981 BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id, states); | 1967 BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id, states); |
1982 break; | 1968 break; |
1983 } | 1969 } |
1984 case NAMED_PROPERTY: { | 1970 case NAMED_PROPERTY: { |
(...skipping 13 matching lines...) Expand all Loading... | |
1998 VisitForValue(property->obj()); | 1984 VisitForValue(property->obj()); |
1999 VisitForValue(property->key()); | 1985 VisitForValue(property->key()); |
2000 FrameStateBeforeAndAfter states(this, property->key()->id()); | 1986 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2001 Node* key = environment()->Pop(); | 1987 Node* key = environment()->Pop(); |
2002 Node* object = environment()->Pop(); | 1988 Node* object = environment()->Pop(); |
2003 value = environment()->Pop(); | 1989 value = environment()->Pop(); |
2004 Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None()); | 1990 Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None()); |
2005 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 1991 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); |
2006 break; | 1992 break; |
2007 } | 1993 } |
1994 case NAMED_SUPER_PROPERTY: { | |
1995 environment()->Push(value); | |
1996 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | |
1997 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | |
1998 FrameStateBeforeAndAfter states(this, property->obj()->id()); | |
1999 Node* home_object = environment()->Pop(); | |
2000 Node* receiver = environment()->Pop(); | |
2001 value = environment()->Pop(); | |
2002 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2003 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, | |
2004 TypeFeedbackId::None()); | |
2005 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | |
2006 break; | |
2007 } | |
2008 case KEYED_SUPER_PROPERTY: { | |
2009 environment()->Push(value); | |
2010 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | |
2011 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | |
2012 VisitForValue(property->key()); | |
2013 FrameStateBeforeAndAfter states(this, property->key()->id()); | |
2014 Node* key = environment()->Pop(); | |
2015 Node* home_object = environment()->Pop(); | |
2016 Node* receiver = environment()->Pop(); | |
2017 value = environment()->Pop(); | |
2018 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value, | |
2019 TypeFeedbackId::None()); | |
2020 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | |
2021 break; | |
2022 } | |
2008 } | 2023 } |
2009 } | 2024 } |
2010 | 2025 |
2011 | 2026 |
2012 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 2027 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
2013 DCHECK(expr->target()->IsValidReferenceExpression()); | 2028 DCHECK(expr->target()->IsValidReferenceExpression()); |
2014 | 2029 |
2015 // Left-hand side can only be a property, a global or a variable slot. | 2030 // Left-hand side can only be a property, a global or a variable slot. |
2016 Property* property = expr->target()->AsProperty(); | 2031 Property* property = expr->target()->AsProperty(); |
2017 LhsKind assign_type = DetermineLhsKind(expr->target()); | 2032 LhsKind assign_type = Property::GetAssignType(property); |
2018 bool needs_frame_state_before = true; | 2033 bool needs_frame_state_before = true; |
2019 | 2034 |
2020 // Evaluate LHS expression. | 2035 // Evaluate LHS expression. |
2021 switch (assign_type) { | 2036 switch (assign_type) { |
2022 case VARIABLE: { | 2037 case VARIABLE: { |
2023 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2038 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2024 if (variable->location() == Variable::PARAMETER || | 2039 if (variable->location() == Variable::PARAMETER || |
2025 variable->location() == Variable::LOCAL || | 2040 variable->location() == Variable::LOCAL || |
2026 variable->location() == Variable::CONTEXT) { | 2041 variable->location() == Variable::CONTEXT) { |
2027 needs_frame_state_before = false; | 2042 needs_frame_state_before = false; |
2028 } | 2043 } |
2029 break; | 2044 break; |
2030 } | 2045 } |
2031 case NAMED_PROPERTY: | 2046 case NAMED_PROPERTY: |
2032 VisitForValue(property->obj()); | 2047 VisitForValue(property->obj()); |
2033 break; | 2048 break; |
2034 case KEYED_PROPERTY: { | 2049 case KEYED_PROPERTY: |
2035 VisitForValue(property->obj()); | 2050 VisitForValue(property->obj()); |
2036 VisitForValue(property->key()); | 2051 VisitForValue(property->key()); |
2037 break; | 2052 break; |
2038 } | 2053 case NAMED_SUPER_PROPERTY: |
2054 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | |
2055 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | |
2056 break; | |
2057 case KEYED_SUPER_PROPERTY: | |
2058 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | |
2059 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | |
2060 VisitForValue(property->key()); | |
2061 break; | |
2039 } | 2062 } |
2040 | 2063 |
2041 BailoutId before_store_id = BailoutId::None(); | 2064 BailoutId before_store_id = BailoutId::None(); |
2042 // Evaluate the value and potentially handle compound assignments by loading | 2065 // Evaluate the value and potentially handle compound assignments by loading |
2043 // the left-hand side value and performing a binary operation. | 2066 // the left-hand side value and performing a binary operation. |
2044 if (expr->is_compound()) { | 2067 if (expr->is_compound()) { |
2045 Node* old_value = NULL; | 2068 Node* old_value = NULL; |
2046 switch (assign_type) { | 2069 switch (assign_type) { |
2047 case VARIABLE: { | 2070 case VARIABLE: { |
2048 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2071 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
(...skipping 20 matching lines...) Expand all Loading... | |
2069 Node* key = environment()->Top(); | 2092 Node* key = environment()->Top(); |
2070 Node* object = environment()->Peek(1); | 2093 Node* object = environment()->Peek(1); |
2071 VectorSlotPair pair = | 2094 VectorSlotPair pair = |
2072 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2095 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2073 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2096 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2074 old_value = BuildKeyedLoad(object, key, pair); | 2097 old_value = BuildKeyedLoad(object, key, pair); |
2075 states.AddToNode(old_value, property->LoadId(), | 2098 states.AddToNode(old_value, property->LoadId(), |
2076 OutputFrameStateCombine::Push()); | 2099 OutputFrameStateCombine::Push()); |
2077 break; | 2100 break; |
2078 } | 2101 } |
2102 case NAMED_SUPER_PROPERTY: { | |
2103 Node* home_object = environment()->Top(); | |
2104 Node* receiver = environment()->Peek(1); | |
2105 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2106 VectorSlotPair pair = | |
2107 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | |
2108 FrameStateBeforeAndAfter states(this, property->obj()->id()); | |
2109 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); | |
2110 states.AddToNode(old_value, property->LoadId(), | |
2111 OutputFrameStateCombine::Push()); | |
2112 break; | |
2113 } | |
2114 case KEYED_SUPER_PROPERTY: { | |
2115 Node* key = environment()->Top(); | |
2116 Node* home_object = environment()->Peek(1); | |
2117 Node* receiver = environment()->Peek(2); | |
2118 VectorSlotPair pair = | |
2119 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | |
2120 FrameStateBeforeAndAfter states(this, property->key()->id()); | |
2121 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | |
2122 states.AddToNode(old_value, property->LoadId(), | |
2123 OutputFrameStateCombine::Push()); | |
2124 break; | |
2125 } | |
2079 } | 2126 } |
2080 environment()->Push(old_value); | 2127 environment()->Push(old_value); |
2081 VisitForValue(expr->value()); | 2128 VisitForValue(expr->value()); |
2082 Node* value; | 2129 Node* value; |
2083 { | 2130 { |
2084 FrameStateBeforeAndAfter states(this, expr->value()->id()); | 2131 FrameStateBeforeAndAfter states(this, expr->value()->id()); |
2085 Node* right = environment()->Pop(); | 2132 Node* right = environment()->Pop(); |
2086 Node* left = environment()->Pop(); | 2133 Node* left = environment()->Pop(); |
2087 value = BuildBinaryOp(left, right, expr->binary_op()); | 2134 value = BuildBinaryOp(left, right, expr->binary_op()); |
2088 states.AddToNode(value, expr->binary_operation()->id(), | 2135 states.AddToNode(value, expr->binary_operation()->id(), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2120 } | 2167 } |
2121 case KEYED_PROPERTY: { | 2168 case KEYED_PROPERTY: { |
2122 Node* key = environment()->Pop(); | 2169 Node* key = environment()->Pop(); |
2123 Node* object = environment()->Pop(); | 2170 Node* object = environment()->Pop(); |
2124 Node* store = | 2171 Node* store = |
2125 BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId()); | 2172 BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId()); |
2126 store_states.AddToNode(store, expr->id(), | 2173 store_states.AddToNode(store, expr->id(), |
2127 ast_context()->GetStateCombine()); | 2174 ast_context()->GetStateCombine()); |
2128 break; | 2175 break; |
2129 } | 2176 } |
2177 case NAMED_SUPER_PROPERTY: { | |
2178 Node* home_object = environment()->Pop(); | |
2179 Node* receiver = environment()->Pop(); | |
2180 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2181 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, | |
2182 expr->AssignmentFeedbackId()); | |
2183 store_states.AddToNode(store, expr->id(), | |
2184 ast_context()->GetStateCombine()); | |
2185 break; | |
2186 } | |
2187 case KEYED_SUPER_PROPERTY: { | |
2188 Node* key = environment()->Pop(); | |
2189 Node* home_object = environment()->Pop(); | |
2190 Node* receiver = environment()->Pop(); | |
2191 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value, | |
2192 expr->AssignmentFeedbackId()); | |
2193 store_states.AddToNode(store, expr->id(), | |
2194 ast_context()->GetStateCombine()); | |
2195 break; | |
2196 } | |
2130 } | 2197 } |
2131 | 2198 |
2132 ast_context()->ProduceValue(value); | 2199 ast_context()->ProduceValue(value); |
2133 } | 2200 } |
2134 | 2201 |
2135 | 2202 |
2136 void AstGraphBuilder::VisitYield(Yield* expr) { | 2203 void AstGraphBuilder::VisitYield(Yield* expr) { |
2137 // TODO(turbofan): Implement yield here. | 2204 // TODO(turbofan): Implement yield here. |
2138 SetStackOverflow(); | 2205 SetStackOverflow(); |
2139 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); | 2206 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); |
2140 } | 2207 } |
2141 | 2208 |
2142 | 2209 |
2143 void AstGraphBuilder::VisitThrow(Throw* expr) { | 2210 void AstGraphBuilder::VisitThrow(Throw* expr) { |
2144 VisitForValue(expr->exception()); | 2211 VisitForValue(expr->exception()); |
2145 Node* exception = environment()->Pop(); | 2212 Node* exception = environment()->Pop(); |
2146 Node* value = BuildThrowError(exception, expr->id()); | 2213 Node* value = BuildThrowError(exception, expr->id()); |
2147 ast_context()->ProduceValue(value); | 2214 ast_context()->ProduceValue(value); |
2148 } | 2215 } |
2149 | 2216 |
2150 | 2217 |
2151 void AstGraphBuilder::VisitProperty(Property* expr) { | 2218 void AstGraphBuilder::VisitProperty(Property* expr) { |
2152 Node* value; | 2219 Node* value; |
brucedawson
2015/06/08 17:24:50
It is not clear that 'value' will always be initia
| |
2220 LhsKind property_kind = Property::GetAssignType(expr); | |
2153 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); | 2221 VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); |
2154 if (expr->key()->IsPropertyName()) { | 2222 switch (property_kind) { |
2155 VisitForValue(expr->obj()); | 2223 case VARIABLE: |
2156 FrameStateBeforeAndAfter states(this, expr->obj()->id()); | 2224 UNREACHABLE(); |
2157 Node* object = environment()->Pop(); | 2225 value = nullptr; |
brucedawson
2015/06/08 17:24:50
i.e.; move this assignment to the variable declara
| |
2158 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | 2226 break; |
2159 value = BuildNamedLoad(object, name, pair); | 2227 case NAMED_PROPERTY: { |
2160 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2228 VisitForValue(expr->obj()); |
2161 } else { | 2229 FrameStateBeforeAndAfter states(this, expr->obj()->id()); |
2162 VisitForValue(expr->obj()); | 2230 Node* object = environment()->Pop(); |
2163 VisitForValue(expr->key()); | 2231 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); |
2164 FrameStateBeforeAndAfter states(this, expr->key()->id()); | 2232 value = BuildNamedLoad(object, name, pair); |
2165 Node* key = environment()->Pop(); | 2233 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
2166 Node* object = environment()->Pop(); | 2234 break; |
2167 value = BuildKeyedLoad(object, key, pair); | 2235 } |
2168 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | 2236 case KEYED_PROPERTY: { |
2237 VisitForValue(expr->obj()); | |
2238 VisitForValue(expr->key()); | |
2239 FrameStateBeforeAndAfter states(this, expr->key()->id()); | |
2240 Node* key = environment()->Pop(); | |
2241 Node* object = environment()->Pop(); | |
2242 value = BuildKeyedLoad(object, key, pair); | |
2243 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | |
2244 break; | |
2245 } | |
2246 case NAMED_SUPER_PROPERTY: { | |
2247 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); | |
2248 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); | |
2249 FrameStateBeforeAndAfter states(this, expr->obj()->id()); | |
2250 Node* home_object = environment()->Pop(); | |
2251 Node* receiver = environment()->Pop(); | |
2252 Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); | |
2253 value = BuildNamedSuperLoad(receiver, home_object, name, pair); | |
2254 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | |
2255 break; | |
2256 } | |
2257 case KEYED_SUPER_PROPERTY: { | |
2258 VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var()); | |
2259 VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object()); | |
2260 VisitForValue(expr->key()); | |
2261 FrameStateBeforeAndAfter states(this, expr->key()->id()); | |
2262 Node* key = environment()->Pop(); | |
2263 Node* home_object = environment()->Pop(); | |
2264 Node* receiver = environment()->Pop(); | |
2265 value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | |
2266 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); | |
2267 break; | |
2268 } | |
2169 } | 2269 } |
2170 ast_context()->ProduceValue(value); | 2270 ast_context()->ProduceValue(value); |
2171 } | 2271 } |
2172 | 2272 |
2173 | 2273 |
2174 void AstGraphBuilder::VisitCall(Call* expr) { | 2274 void AstGraphBuilder::VisitCall(Call* expr) { |
2175 Expression* callee = expr->expression(); | 2275 Expression* callee = expr->expression(); |
2176 Call::CallType call_type = expr->GetCallType(isolate()); | 2276 Call::CallType call_type = expr->GetCallType(isolate()); |
2177 | 2277 |
2178 // Prepare the callee and the receiver to the function call. This depends on | 2278 // Prepare the callee and the receiver to the function call. This depends on |
(...skipping 22 matching lines...) Expand all Loading... | |
2201 Node* pair = NewNode(op, current_context(), name); | 2301 Node* pair = NewNode(op, current_context(), name); |
2202 callee_value = NewNode(common()->Projection(0), pair); | 2302 callee_value = NewNode(common()->Projection(0), pair); |
2203 receiver_value = NewNode(common()->Projection(1), pair); | 2303 receiver_value = NewNode(common()->Projection(1), pair); |
2204 | 2304 |
2205 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2305 PrepareFrameState(pair, expr->EvalOrLookupId(), |
2206 OutputFrameStateCombine::Push(2)); | 2306 OutputFrameStateCombine::Push(2)); |
2207 break; | 2307 break; |
2208 } | 2308 } |
2209 case Call::PROPERTY_CALL: { | 2309 case Call::PROPERTY_CALL: { |
2210 Property* property = callee->AsProperty(); | 2310 Property* property = callee->AsProperty(); |
2211 VisitForValue(property->obj()); | |
2212 Node* object = environment()->Top(); | |
2213 VectorSlotPair pair = | 2311 VectorSlotPair pair = |
2214 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2312 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2215 if (property->key()->IsPropertyName()) { | 2313 if (!property->IsSuperAccess()) { |
Michael Starzinger
2015/06/05 13:28:19
Could this be modeled as a switch over the LhsKind
arv (Not doing code reviews)
2015/06/05 13:50:26
I tried it but reverted back to the ifs. I found t
Michael Starzinger
2015/06/05 13:53:23
Acknowledged. OK, then let's leave it as it is.
| |
2216 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2314 VisitForValue(property->obj()); |
2217 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2315 Node* object = environment()->Top(); |
2218 callee_value = BuildNamedLoad(object, name, pair); | 2316 |
2219 states.AddToNode(callee_value, property->LoadId(), | 2317 if (property->key()->IsPropertyName()) { |
2220 OutputFrameStateCombine::Push()); | 2318 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2319 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2320 callee_value = BuildNamedLoad(object, name, pair); | |
2321 states.AddToNode(callee_value, property->LoadId(), | |
2322 OutputFrameStateCombine::Push()); | |
2323 } else { | |
2324 VisitForValue(property->key()); | |
2325 FrameStateBeforeAndAfter states(this, property->key()->id()); | |
2326 Node* key = environment()->Pop(); | |
2327 callee_value = BuildKeyedLoad(object, key, pair); | |
2328 states.AddToNode(callee_value, property->LoadId(), | |
2329 OutputFrameStateCombine::Push()); | |
2330 } | |
2331 receiver_value = environment()->Pop(); | |
2332 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | |
2333 // object for sloppy callees. This could also be modeled explicitly | |
2334 // here, | |
2335 // thereby obsoleting the need for a flag to the call operator. | |
2336 flags = CALL_AS_METHOD; | |
2337 | |
2221 } else { | 2338 } else { |
2222 VisitForValue(property->key()); | 2339 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2223 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2340 VisitForValue( |
2224 Node* key = environment()->Pop(); | 2341 property->obj()->AsSuperPropertyReference()->home_object()); |
2225 callee_value = BuildKeyedLoad(object, key, pair); | 2342 Node* home_object = environment()->Pop(); |
2226 states.AddToNode(callee_value, property->LoadId(), | 2343 receiver_value = environment()->Pop(); |
2227 OutputFrameStateCombine::Push()); | 2344 if (property->key()->IsPropertyName()) { |
2345 FrameStateBeforeAndAfter states(this, property->obj()->id()); | |
2346 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2347 callee_value = | |
2348 BuildNamedSuperLoad(receiver_value, home_object, name, pair); | |
2349 states.AddToNode(callee_value, property->LoadId(), | |
2350 OutputFrameStateCombine::Push()); | |
2351 | |
2352 } else { | |
2353 VisitForValue(property->key()); | |
2354 FrameStateBeforeAndAfter states(this, property->key()->id()); | |
2355 Node* key = environment()->Pop(); | |
2356 callee_value = | |
2357 BuildKeyedSuperLoad(receiver_value, home_object, key, pair); | |
2358 states.AddToNode(callee_value, property->LoadId(), | |
2359 OutputFrameStateCombine::Push()); | |
2360 } | |
2228 } | 2361 } |
2229 receiver_value = environment()->Pop(); | 2362 |
2230 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | |
2231 // object for sloppy callees. This could also be modeled explicitly here, | |
2232 // thereby obsoleting the need for a flag to the call operator. | |
2233 flags = CALL_AS_METHOD; | |
2234 break; | 2363 break; |
2235 } | 2364 } |
2236 case Call::SUPER_CALL: | 2365 case Call::SUPER_CALL: |
2237 // TODO(dslomov): Implement super calls. | 2366 // TODO(dslomov): Implement super calls. |
2238 callee_value = jsgraph()->UndefinedConstant(); | 2367 callee_value = jsgraph()->UndefinedConstant(); |
2239 receiver_value = jsgraph()->UndefinedConstant(); | 2368 receiver_value = jsgraph()->UndefinedConstant(); |
2240 SetStackOverflow(); | 2369 SetStackOverflow(); |
2241 break; | 2370 break; |
2242 case Call::POSSIBLY_EVAL_CALL: | 2371 case Call::POSSIBLY_EVAL_CALL: |
2243 possibly_eval = true; | 2372 possibly_eval = true; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2393 UNREACHABLE(); | 2522 UNREACHABLE(); |
2394 } | 2523 } |
2395 } | 2524 } |
2396 | 2525 |
2397 | 2526 |
2398 void AstGraphBuilder::VisitCountOperation(CountOperation* expr) { | 2527 void AstGraphBuilder::VisitCountOperation(CountOperation* expr) { |
2399 DCHECK(expr->expression()->IsValidReferenceExpression()); | 2528 DCHECK(expr->expression()->IsValidReferenceExpression()); |
2400 | 2529 |
2401 // Left-hand side can only be a property, a global or a variable slot. | 2530 // Left-hand side can only be a property, a global or a variable slot. |
2402 Property* property = expr->expression()->AsProperty(); | 2531 Property* property = expr->expression()->AsProperty(); |
2403 LhsKind assign_type = DetermineLhsKind(expr->expression()); | 2532 LhsKind assign_type = Property::GetAssignType(property); |
2404 | 2533 |
2405 // Reserve space for result of postfix operation. | 2534 // Reserve space for result of postfix operation. |
2406 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); | 2535 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); |
2407 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); | 2536 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); |
2408 | 2537 |
2409 // Evaluate LHS expression and get old value. | 2538 // Evaluate LHS expression and get old value. |
2410 Node* old_value = NULL; | 2539 Node* old_value = NULL; |
2411 int stack_depth = -1; | 2540 int stack_depth = -1; |
2412 switch (assign_type) { | 2541 switch (assign_type) { |
2413 case VARIABLE: { | 2542 case VARIABLE: { |
(...skipping 26 matching lines...) Expand all Loading... | |
2440 Node* key = environment()->Top(); | 2569 Node* key = environment()->Top(); |
2441 Node* object = environment()->Peek(1); | 2570 Node* object = environment()->Peek(1); |
2442 VectorSlotPair pair = | 2571 VectorSlotPair pair = |
2443 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 2572 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
2444 old_value = BuildKeyedLoad(object, key, pair); | 2573 old_value = BuildKeyedLoad(object, key, pair); |
2445 states.AddToNode(old_value, property->LoadId(), | 2574 states.AddToNode(old_value, property->LoadId(), |
2446 OutputFrameStateCombine::Push()); | 2575 OutputFrameStateCombine::Push()); |
2447 stack_depth = 2; | 2576 stack_depth = 2; |
2448 break; | 2577 break; |
2449 } | 2578 } |
2579 case NAMED_SUPER_PROPERTY: { | |
2580 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | |
2581 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | |
2582 FrameStateBeforeAndAfter states(this, property->obj()->id()); | |
2583 Node* home_object = environment()->Top(); | |
2584 Node* receiver = environment()->Peek(1); | |
2585 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2586 VectorSlotPair pair = | |
2587 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | |
2588 old_value = BuildNamedSuperLoad(receiver, home_object, name, pair); | |
2589 states.AddToNode(old_value, property->LoadId(), | |
2590 OutputFrameStateCombine::Push()); | |
2591 stack_depth = 2; | |
2592 break; | |
2593 } | |
2594 case KEYED_SUPER_PROPERTY: { | |
2595 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | |
2596 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | |
2597 VisitForValue(property->key()); | |
2598 FrameStateBeforeAndAfter states(this, property->obj()->id()); | |
2599 Node* key = environment()->Top(); | |
2600 Node* home_object = environment()->Peek(1); | |
2601 Node* receiver = environment()->Peek(2); | |
2602 VectorSlotPair pair = | |
2603 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | |
2604 old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair); | |
2605 states.AddToNode(old_value, property->LoadId(), | |
2606 OutputFrameStateCombine::Push()); | |
2607 stack_depth = 3; | |
2608 break; | |
2609 } | |
2450 } | 2610 } |
2451 | 2611 |
2452 // Convert old value into a number. | 2612 // Convert old value into a number. |
2453 old_value = NewNode(javascript()->ToNumber(), old_value); | 2613 old_value = NewNode(javascript()->ToNumber(), old_value); |
2454 PrepareFrameState(old_value, expr->ToNumberId(), | 2614 PrepareFrameState(old_value, expr->ToNumberId(), |
2455 OutputFrameStateCombine::Push()); | 2615 OutputFrameStateCombine::Push()); |
2456 | 2616 |
2457 // TODO(titzer): combine this framestate with the above? | 2617 // TODO(titzer): combine this framestate with the above? |
2458 FrameStateBeforeAndAfter store_states(this, assign_type == KEYED_PROPERTY | 2618 FrameStateBeforeAndAfter store_states(this, assign_type == KEYED_PROPERTY |
2459 ? expr->ToNumberId() | 2619 ? expr->ToNumberId() |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2499 Node* key = environment()->Pop(); | 2659 Node* key = environment()->Pop(); |
2500 Node* object = environment()->Pop(); | 2660 Node* object = environment()->Pop(); |
2501 Node* store = | 2661 Node* store = |
2502 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId()); | 2662 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId()); |
2503 environment()->Push(value); | 2663 environment()->Push(value); |
2504 store_states.AddToNode(store, expr->AssignmentId(), | 2664 store_states.AddToNode(store, expr->AssignmentId(), |
2505 OutputFrameStateCombine::Ignore()); | 2665 OutputFrameStateCombine::Ignore()); |
2506 environment()->Pop(); | 2666 environment()->Pop(); |
2507 break; | 2667 break; |
2508 } | 2668 } |
2669 case NAMED_SUPER_PROPERTY: { | |
2670 Node* home_object = environment()->Pop(); | |
2671 Node* receiver = environment()->Pop(); | |
2672 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
2673 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, | |
2674 expr->CountStoreFeedbackId()); | |
2675 environment()->Push(value); | |
2676 store_states.AddToNode(store, expr->AssignmentId(), | |
2677 OutputFrameStateCombine::Ignore()); | |
2678 environment()->Pop(); | |
2679 break; | |
2680 } | |
2681 case KEYED_SUPER_PROPERTY: { | |
2682 Node* key = environment()->Pop(); | |
2683 Node* home_object = environment()->Pop(); | |
2684 Node* receiver = environment()->Pop(); | |
2685 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value, | |
2686 expr->CountStoreFeedbackId()); | |
2687 environment()->Push(value); | |
2688 store_states.AddToNode(store, expr->AssignmentId(), | |
2689 OutputFrameStateCombine::Ignore()); | |
2690 environment()->Pop(); | |
2691 break; | |
2692 } | |
2509 } | 2693 } |
2510 | 2694 |
2511 // Restore old value for postfix expressions. | 2695 // Restore old value for postfix expressions. |
2512 if (is_postfix) value = environment()->Pop(); | 2696 if (is_postfix) value = environment()->Pop(); |
2513 | 2697 |
2514 ast_context()->ProduceValue(value); | 2698 ast_context()->ProduceValue(value); |
2515 } | 2699 } |
2516 | 2700 |
2517 | 2701 |
2518 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 2702 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2924 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3108 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
2925 // This should never lazy deopt, so it is fine to send invalid bailout id. | 3109 // This should never lazy deopt, so it is fine to send invalid bailout id. |
2926 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3110 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
2927 BuildVariableAssignment(rest, object, Token::ASSIGN, BailoutId::None(), | 3111 BuildVariableAssignment(rest, object, Token::ASSIGN, BailoutId::None(), |
2928 states); | 3112 states); |
2929 | 3113 |
2930 return object; | 3114 return object; |
2931 } | 3115 } |
2932 | 3116 |
2933 | 3117 |
3118 Node* AstGraphBuilder::BuildThisFunctionVar(Variable* this_function_var) { | |
3119 if (this_function_var == nullptr) return nullptr; | |
3120 | |
3121 Node* this_function = GetFunctionClosure(); | |
3122 FrameStateBeforeAndAfter states(this, BailoutId::None()); | |
3123 BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST, | |
3124 BailoutId::None(), states); | |
3125 return this_function; | |
3126 } | |
3127 | |
3128 | |
2934 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 3129 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, |
2935 Node* not_hole) { | 3130 Node* not_hole) { |
2936 Node* the_hole = jsgraph()->TheHoleConstant(); | 3131 Node* the_hole = jsgraph()->TheHoleConstant(); |
2937 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 3132 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); |
2938 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 3133 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, |
2939 for_hole, not_hole); | 3134 for_hole, not_hole); |
2940 } | 3135 } |
2941 | 3136 |
2942 | 3137 |
2943 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable, | 3138 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable, |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3250 | 3445 |
3251 | 3446 |
3252 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, | 3447 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, |
3253 Node* value, TypeFeedbackId id) { | 3448 Node* value, TypeFeedbackId id) { |
3254 const Operator* op = | 3449 const Operator* op = |
3255 javascript()->StoreNamed(language_mode(), MakeUnique(name)); | 3450 javascript()->StoreNamed(language_mode(), MakeUnique(name)); |
3256 return Record(js_type_feedback_, NewNode(op, object, value), id); | 3451 return Record(js_type_feedback_, NewNode(op, object, value), id); |
3257 } | 3452 } |
3258 | 3453 |
3259 | 3454 |
3455 Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object, | |
3456 Handle<Name> name, | |
3457 const VectorSlotPair& feedback) { | |
3458 Node* name_node = jsgraph()->Constant(name); | |
3459 const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3); | |
3460 Node* value = NewNode(op, receiver, home_object, name_node); | |
3461 return Record(js_type_feedback_, value, feedback.slot()); | |
Michael Starzinger
2015/06/05 13:28:19
Just for clarification: My understanding is that w
arv (Not doing code reviews)
2015/06/05 13:50:26
I think that is right. At some point we probably w
Michael Starzinger
2015/06/05 13:53:23
Acknowledged.
| |
3462 } | |
3463 | |
3464 | |
3465 Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object, | |
3466 Node* key, | |
3467 const VectorSlotPair& feedback) { | |
3468 const Operator* op = | |
3469 javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3); | |
3470 Node* value = NewNode(op, receiver, home_object, key); | |
3471 return Record(js_type_feedback_, value, feedback.slot()); | |
3472 } | |
3473 | |
3474 | |
3475 Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object, | |
3476 Node* key, Node* value, | |
3477 TypeFeedbackId id) { | |
3478 Runtime::FunctionId function_id = is_strict(language_mode()) | |
3479 ? Runtime::kStoreKeyedToSuper_Strict | |
3480 : Runtime::kStoreKeyedToSuper_Sloppy; | |
3481 const Operator* op = javascript()->CallRuntime(function_id, 4); | |
3482 Node* result = NewNode(op, receiver, home_object, key, value); | |
3483 return Record(js_type_feedback_, result, id); | |
3484 } | |
3485 | |
3486 | |
3487 Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object, | |
3488 Handle<Name> name, Node* value, | |
3489 TypeFeedbackId id) { | |
3490 Node* name_node = jsgraph()->Constant(name); | |
3491 Runtime::FunctionId function_id = is_strict(language_mode()) | |
3492 ? Runtime::kStoreToSuper_Strict | |
3493 : Runtime::kStoreToSuper_Sloppy; | |
3494 const Operator* op = javascript()->CallRuntime(function_id, 4); | |
3495 Node* result = NewNode(op, receiver, home_object, name_node, value); | |
3496 return Record(js_type_feedback_, result, id); | |
3497 } | |
3498 | |
3499 | |
3260 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { | 3500 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { |
3261 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, | 3501 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
3262 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); | 3502 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); |
3263 } | 3503 } |
3264 | 3504 |
3265 | 3505 |
3266 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { | 3506 Node* AstGraphBuilder::BuildLoadBuiltinsObject() { |
3267 Node* global = BuildLoadGlobalObject(); | 3507 Node* global = BuildLoadGlobalObject(); |
3268 Node* builtins = | 3508 Node* builtins = |
3269 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); | 3509 BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset); |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3791 // Phi does not exist yet, introduce one. | 4031 // Phi does not exist yet, introduce one. |
3792 value = NewPhi(inputs, value, control); | 4032 value = NewPhi(inputs, value, control); |
3793 value->ReplaceInput(inputs - 1, other); | 4033 value->ReplaceInput(inputs - 1, other); |
3794 } | 4034 } |
3795 return value; | 4035 return value; |
3796 } | 4036 } |
3797 | 4037 |
3798 } // namespace compiler | 4038 } // namespace compiler |
3799 } // namespace internal | 4039 } // namespace internal |
3800 } // namespace v8 | 4040 } // namespace v8 |
OLD | NEW |